создание подкласса QGraphicsView и использование mouseMoveEvent и mouseClickEvent портит перемещение QGraphicsItems в моей сцене - PullRequest
0 голосов
/ 27 февраля 2020

Pyside2: я создаю подклассы QGraphicsView и добавляю функции масштабирования и панорамирования в mouseClickEvent и mouseMoveEvent.

Когда я делаю это, элементы QGraphicsItems в моей сцене, в которых активированы Selectable и Moveable, не перемещаются должным образом после первого щелкните и перетащите.

Они отлично двигаются при первом щелчке и перетаскивании, но если я щелкну и перетащу их снова, они вернутся назад в положение, в котором они были созданы, и переместятся оттуда.

Здесь что имею:

class ZoomView(QGraphicsView):
    '''
    View class with zoom enabled
    '''
    def __init__(self):
        super(ZoomView, self).__init__()
        self.alt_key = False
        self.ctrl_key = False
        self.mid_button = False
        self.left_button = False

        self.mouse_pos = None
        self.orig_pos = None

        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(2)
        sizePolicy.setHeightForWidth(True)

        self.setSizePolicy(sizePolicy)
        self.setMinimumSize(QtCore.QSize(0, 0))
        self.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing)

        self.setResizeAnchor(QGraphicsView.NoAnchor)
        self.setObjectName("PickerView")
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Alt:
            self.alt_key = True
        elif event.key() == QtCore.Qt.Key_Control:
            self.ctrl_key = True
        else:
            return super(ZoomView, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        if event.key() == QtCore.Qt.Key_Alt:
            self.alt_key = False
        elif event.key() == QtCore.Qt.Key_Control:
            self.ctrl_key = False
        else:
            return super(ZoomView, self).keyReleaseEvent(event)

    def mousePressEvent(self, event):

        self.mouse_pos = event.pos()
        if event.button() == QtCore.Qt.MidButton:
            self.mid_button = True

        if event.button() == QtCore.Qt.LeftButton:
            super(ZoomView, self).mousePressEvent(event)
            self.left_button = True

    def mouseReleaseEvent(self, event):
        if event.button() == QtCore.Qt.MidButton:
            self.mid_button = False
        elif event.button() == QtCore.Qt.LeftButton:
            self.left_button = False
        else:
            return super(ZoomView, self).mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):

        if event.buttons() == QtCore.Qt.NoButton:
            return super(ZoomView, self).mouseMoveEvent(event)

        new_pos = event.pos()
        diff_x = self.mouse_pos.x() - new_pos.x()
        diff_y = self.mouse_pos.y() - new_pos.y()
        if self.alt_key and self.mid_button and not self.left_button:
            # pan the screen

            h_scroll = self.horizontalScrollBar()
            v_scroll = self.verticalScrollBar()

            H_scrollFinal = h_scroll.value() + diff_x
            V_scrollFinal = v_scroll.value() + diff_y
            h_scroll.setValue(H_scrollFinal)
            v_scroll.setValue(V_scrollFinal)

            self.mouse_pos = new_pos

        elif self.alt_key and self.left_button and self.mid_button:
            # zoom
            actualScale = self.transform().m11()
            coefDdiff_x = diff_x * 0.004
            scaleFactor = actualScale - coefDdiff_x
            if scaleFactor > 0.05 and scaleFactor < 3:
                matrice = QtGui.QTransform(scaleFactor, 0, 0, 0, scaleFactor, 0, 0, 0, 1)
                self.setTransform(matrice, combine=False)
                h_scroll = self.horizontalScrollBar()
                v_scroll = self.verticalScrollBar()

                self.mouse_pos = new_pos

        else:
            return super(ZoomView, self).mouseMoveEvent(event)

1 Ответ

0 голосов
/ 04 марта 2020

ОК нашел решение.

Когда вы создаете подкласс QGraphicsView и переопределяете эти методы мыши

mousePressEvent()
mouseMoveEvent()
mouseReleaseEvent()

, вам нужно поместить оператор "if" в начале каждого метода, который проверяет, находится ли мышь над одним из ваши вещи перед запуском пользовательского кода увеличения / панорамирования. Если мышь находится над элементом, таким как прямоугольник или эллипс, просто запустите super этого метода и вернитесь. Также, если выбран прямоугольник или эллипс, запустите super и вернитесь.

Вот пример:

class MyView(QGraphicsView):

    def mousePressEvent(self, event):

        # check if clicking on a button first or if a button is selected
        scene = self.scene()
        items = scene.items(event.localPos())

        if self.selected_items():
            super(Picker_View, self).mousePressEvent(event)
            return

        if items and isinstance(items[0], Ellipse_Button):
            # QGraphicsScene.mousePressEvent(self, event)
            super(Picker_View, self).mousePressEvent(event)
            return

        self.foo()

    def selected_items(self):
        '''
        Checks if any items in the graphics scene are selected
        Returns:
            (boolean)

        '''
        scene = self.scene()
        elements = scene.items()
        for element in elements:
            if element.isSelected():
                return True
            else:
                pass
        return False
...