'How to translate/drag/move QGraphicsScene?

I know this question was answered a lot of times especially in C++ version of Qt, but I am not so good in C++ and I can't find the solution.

I have a code with QGraphicsView with rectangle made out of QGraphicsPolygonItem in center. I am trying to find a way to make QGraphicsScene translatable/movable/dragable by a user(anything would be okay, I am just trying to give a user an option to move around scene). But none of my tries would work.

I tried setting :

  • self.horizontalScrollBar().setValue() and self.verticalScrollBar().setValue()

  • self._scene.setSceneRect(x,y,w,h)

  • setting anchor to AnchorUnderMouse and NoAnchor

  • using translate()

None of it makes my scene move... Only thing which made my scene move is setSceneRect(), but once I put it under mouseMoveEvent(self,event) it stops working. Can somebody help me to learn how to move around that rectangle in scene ?

Code:

from PyQt5.QtGui import QColor, QPolygonF, QPen, QBrush
from PyQt5.QtCore import Qt, QPointF, QPoint, pyqtSignal
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QGraphicsView, QGraphicsScene, QGraphicsPolygonItem, QApplication, \
    QFrame, QSizePolicy

points_list = [[60.1, 19.6, 0.0], [60.1, 6.5, 0.0], [60.1, -6.5, 0.0], [60.1, -19.6, 0.0], [60.1, -19.6, 0.0],
               [20.0, -19.6, 0.0], [-20, -19.6, 0.0], [-60.1, -19.6, 0.0], [-60.1, -19.6, 0.0], [-60.1, -6.5, 0.0],
               [-60.1, 6.5, 0.0], [-60.1, 19.6, 0.0], [-60.1, 19.6, 0.0], [-20.0, 19.6, 0.0], [20.0, 19.6, 0.0],
               [60.1, 19.6, 0.0]]


class MainWindow(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent=parent)
        self.create()

    def create(self, **kwargs):
        main_layout = QVBoxLayout()
        graphics = MainGraphicsWidget()
        main_layout.addWidget(graphics)
        self.setLayout(main_layout)

class MainGraphicsWidget(QGraphicsView):
    zoom_signal = pyqtSignal(bool)

    def __init__(self, parent=None):
        super(MainGraphicsWidget, self).__init__(parent)
        self._scene = QGraphicsScene(backgroundBrush=Qt.gray)
        self.__zoom = 0
        self.setScene(self._scene)
        self.setTransformationAnchor(QGraphicsView.NoAnchor)
        #self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setBackgroundBrush(QBrush(QColor(30, 30, 30)))
        self.setFrameShape(QFrame.NoFrame)
        self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
        self.sceneRect = self._scene.sceneRect()
        self.testButton = GraphicsButton()
        self._scene.addItem(self.testButton)
        #self.horizontalScrollBar().setValue(199)
        #self.verticalScrollBar().setValue(500)

    def mouseMoveEvent(self, event):
        modifierPressed = QApplication.keyboardModifiers()
        if (modifierPressed & Qt.AltModifier) == Qt.AltModifier and event.buttons() == Qt.LeftButton:
            #self._scene.setSceneRect(event.pos().x(), event.pos().y(), self.sceneRect.width(), self.sceneRect.height())
            pass

        super(MainGraphicsWidget, self).mouseMoveEvent(event)

    def wheelEvent(self, event):
        if event.angleDelta().y() > 0:
            factor = 1.25
            self.__zoom += 1
        else:
            factor = 0.8
            self.__zoom -= 1
        self.scale(factor, factor)
        self.zoom_signal.emit(self.__zoom < 10)


class GraphicsButton(QGraphicsPolygonItem):
    def __init__(self, parent=None):
        super(GraphicsButton, self).__init__(parent)
        self.myPolygon = QPolygonF([QPointF(v1, v2) for v1, v2, v3 in points_list])
        self.setPen(QPen(QColor(0, 0, 0), 0, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin))
        self.setPolygon(self.myPolygon)
        self.setBrush(QColor(220, 40, 30))


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = MainWindow()
    window.setGeometry(500, 100, 500, 900)
    window.show()
    sys.exit(app.exec_())


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source