예제 #1
0
class Magnifier(QtGui.QGraphicsPixmapItem):
    def __init__(self, main, parent=None, img=None, graphic=None, scene=None, police=None, texte=None):
        super(Magnifier, self).__init__(parent, scene)
        self.main = main
        d = dict(shape="square",
                    width=0,
                    height=0,
                    img=img,
                    police=police,
                    texte=texte,
                    graphic=graphic,
                    scene=scene,
                    pix=None,
                    cur_pos=None,
                    old_X=None,
                    old_Y=None)
        for key, value in d.items():
            setattr(self, key, value)

        self.setFlags(QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIsFocusable)


        self.setAcceptHoverEvents(True)
        self._moved = Moved()


    # Create signals
    # Signals are class defined at the end of this script
    # http://docs.python.org/howto/descriptor.html

    def positionChanged():
        def fget(self):
            return self._moved.positionChanged
        return locals()
    positionChanged = property(**positionChanged())


    def set_size(self, width, height):
        self.width = self.montexte.size().width()
        self.height = self.montexte.size().height()

    def setup(self):
        """setup the magnifier.

        """
        self.cur_pos = self.__get_center()
        self.setPos(self.cur_pos[2], self.cur_pos[3])
        self.__create_magnifier()
        if not self.old_X:
            self.recenter_magnifying_glass()
        self.old_X, self.old_Y = self.pos().x(), self.pos().y()


    def __create_magnifier(self):
        """Call functions to build the magnifying glass.
        """
        self.__set_sttext()
        self.orig = self.__get_orig_center()
        self.__set_square()


    def __set_sttext(self):
        mat = QTransform()
        self.montexte = QStaticText(self.texte)
        self.montexte.prepare(mat, self.police)
        self.set_size(self.montexte.size().width(), self.montexte.size().height())
        return self.montexte

    def __set_square(self):

        self.txt = self.__set_sttext()
        rect = QtCore.QRect(0, 0, self.width, self.height)
        color = QtGui.QColor()
        color.setRgb(0, 0, 0, 0)
        self.pix = QtGui.QPixmap(QtCore.QSize(self.width + 2, self.height + 2))
        self.pix.fill(color)
        painter = QtGui.QPainter()
        painter.begin(self.pix)
        painter.setFont(self.police)
        painter.drawStaticText(0, 0, self.montexte)
        painter.end()
        self.setPixmap(self.pix)
        return self.pix

    def __update(self, x, y):
        """Update the original coordinates when the magnifying glass is moved.

        """
        self.orig[2] += x
        self.orig[3] += y


    def move_by(self, x, y):
        self.moveBy(x, y)
        self.__update(x, y)

    def __get_center(self):
        """Return the center of the scene.

        This assume both scene and image have the same geometry.

        Returns:
        list[center X, center Y, top left x, top left Y]
        """
        cX, cY = int(self.scene.width() / 2), int(self.scene.height() / 2)
        posX, posY = cX - int(self.width / 2), cY - int(self.height / 2)
        return [cX, cY, posX, posY]


    def get_pos(self):
        """Return position of magnifying glass.

        Returns:
        QPointF(float, float)
        """
        return self.pos()

    def set_pos(self, pos):
        """Move magnifying glass to pos.

        Keyword arguments:
        pos -- QPointF
        """
        if isinstance(pos, QtCore.QPointF):
            X, Y = pos.x(), pos.y()
        else:
            X, Y = pos[0], pos[1]
        cur = self.pos()
        m_X, m_Y = X - self.pos().x(), Y - self.pos().y()
        self.moveBy(m_X, m_Y)
        self.__update(m_X, m_Y)
        self.positionChanged.emit([cur.x(), cur.y(), X, Y])

    def __get_orig_center(self):
        """Return the original position at the creation of the magnifier.

        Returns :
        list -- center of pixmap magnified and corner top left.
        """
        cX, cY = int(self.graphic.width() / 2), int(self.graphic.height() / 2)
        posX, posY = cX - int(self.width / 2), cY - int(self.height / 2)
        return [cX, cY, posX, posY]

    def recenter_magnifying_glass(self):
        """Move the magnifying glass from center image to center graphicsView.

        """
        timer = QtCore.QTimeLine(1000);
        timer.setFrameRange(0, 50)
        self.animation = QtGui.QGraphicsItemAnimation()
        self.animation.setItem(self);
        self.animation.setTimeLine(timer)

        c = self.width / 2.0
        dest = self.graphic.mapToScene(self.graphic.width() / 2 - c, self.graphic.height() / 2 - c)
        deltaX = dest.x() - self.pos().x()
        deltaY = dest.y() - self.pos().y()
        j, k, l, m = deltaX / 50, deltaY / 50, self.pos().x(), self.pos().y()
        for i in range (50):
            l, m = l + j, m + k
            self.animation.setPosAt(i / 50.0, QtCore.QPointF(l, m))
            self.__update(j, k)
        timer.start()


    #--------------------------------
    # Events
    #--------------------------------

    def mousePressEvent(self, event, auto=0):
        # auto = 0 if event is caused by self
        # auto = 1 if event is given by other, i.e. event filter of main
        if auto:
            pos = self.graphic.mapToScene(event.pos())
        else:
            pos = event.scenePos()
        if event.button() == 1:
            self.old_X, self.old_Y = pos.x(), pos.y()
            event.accept()
        else:
            event.ignore()


    def mouseMoveEvent(self, event, auto=0):
        # auto = 0 if event is caused by self
        # auto = 1 if event is given by other, i.e. event filter of main
        if auto:
            pos = self.graphic.mapToScene(event.pos())
        else:
            pos = event.scenePos()
        if event.button() == 2:
            return
        cur = self.pos()
        X, Y = pos.x(), pos.y()
        m_X, m_Y = X - self.old_X, Y - self.old_Y
        self.old_X, self.old_Y = X, Y
        self.moveBy(m_X, m_Y)
        self.__update(m_X, m_Y)
        event.accept()

    def hoverEnterEvent(self, event):
        shape = QtGui.QPixmap("resources/cross_cursor_32.png")
        cursor = QtGui.QCursor(shape, -1, -1)
        self.setCursor(cursor)

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.quit()

        elif event.key() == 16777234:
            # arrow LEFT
            self.move_by(-5, 0)
            self.positionChanged.emit([self.pos().x() + 5, self.pos().y(),
                                    self.pos().x(), self.pos().y()])

        elif event.key() == 16777235:
            # arrow UP
            self.move_by(0, -5)
            self.positionChanged.emit([self.pos().x(), self.pos().y() + 5,
                                    self.pos().x(), self.pos().y()])

        elif event.key() == 16777236:
            # arrow RIGHT
            self.move_by(5, 0)
            self.positionChanged.emit([self.pos().x() - 5, self.pos().y(),
                                    self.pos().x(), self.pos().y()])

        elif event.key() == 16777237:
            # arrow DOWN
            self.move_by(0, 5)
            self.positionChanged.emit([self.pos().x(), self.pos().y() - 5,
                                    self.pos().x(), self.pos().y()])

        elif event.key() == 83:
            # Key S used for enable / disable shadow effect
            try:
                self.main.shadow.setEnabled(not self.main.shadow.isEnabled())
            except:
                pass