【问题标题】:pyqt add rectangle in Qgraphicsscenepyqt在Qgraphicsscene中添加矩形
【发布时间】:2019-03-14 16:06:04
【问题描述】:

我有这样的场景

class Scene(QtWidgets.QGraphicsScene):
    def __init__(self, parent=None):
        super(Scene, self).__init__(parent)

    def mousePressEvent(self, event):
        print('scene pressed')
        self.wid = MyRect(event.pos(), event.pos())
        self.addItem(self.wid)
        self.wid.show()

我希望带有画家、鼠标事件等的 MyRect(QtWidgets.QGraphicsRectItem) 类是一个可拖动的矩形。 MyRect 中的所有内容

所以我可以在场景中有很多矩形,甚至在它们之间画线之后等等(一种图表应用程序),但在 MyRect、MyLine 等中保留与对象相关的可编辑选项。

我想:

class MyRect(QtWidgets.QGraphicsRectItem):
    def __init__(self, begin, end, parent=None):
        super().__init__(parent)
        self.begin = begin
        self.end = end

    def paintEvent(self, event):
        print('painting')
        qp = QtGui.QPainter(self)
        qp.drawRect(QtCore.QRect(self.begin, self.end))

    def mousePressEvent(self, event):
        self.begin = event.pos()
        self.end = event.pos()
        self.update()

    def mouseMoveEvent(self, event):
        self.end = event.pos()
        self.update()

    def mouseReleaseEvent(self, event):
        self.begin = event.pos()
        self.end = event.pos()
        self.update()

但我不工作(绘制事件未启动,而场景中的 mousepressed 事件已启动)

我没有通过网络找到我想要的东西,所以开始尝试自己做。我很确定这是一个必须知道的起点,但我找不到它

【问题讨论】:

    标签: python pyqt pyqt5 qgraphicsview qgraphicsscene


    【解决方案1】:

    首先,QGraphicsItem 不是 QWidget,所以它有那些事件并且不直接处理它们,这就是 QGraphicsView 和 QGraphicsScene 所做的。比如你说你想要一个可移动的矩形,因为那个任务很简单,就是 QGraphicsView,没必要覆盖:

    from PyQt5 import QtCore, QtWidgets
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            scene = QtWidgets.QGraphicsScene(self)
            view = QtWidgets.QGraphicsView(scene)
            self.setCentralWidget(view)
    
            rect_item = QtWidgets.QGraphicsRectItem(QtCore.QRectF(0, 0, 100, 100))
            rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
            scene.addItem(rect_item) 
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    如果你想改变绘制矩形的方式,你必须覆盖paint()方法,如下所示:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class RectItem(QtWidgets.QGraphicsRectItem):
        def paint(self, painter, option, widget=None):
            super(RectItem, self).paint(painter, option, widget)
            painter.save()
            painter.setRenderHint(QtGui.QPainter.Antialiasing)
            painter.setBrush(QtCore.Qt.red)
            painter.drawEllipse(option.rect)
            painter.restore()
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            scene = QtWidgets.QGraphicsScene(self)
            view = QtWidgets.QGraphicsView(scene)
            self.setCentralWidget(view)
    
            rect_item = RectItem(QtCore.QRectF(0, 0, 100, 100))
            rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
            scene.addItem(rect_item) 
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    更新:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    class GraphicsScene(QtWidgets.QGraphicsScene):
        def __init__(self, parent=None):
            super(GraphicsScene, self).__init__(QtCore.QRectF(-500, -500, 1000, 1000), parent)
            self._start = QtCore.QPointF()
            self._current_rect_item = None
    
        def mousePressEvent(self, event):
            if self.itemAt(event.scenePos(), QtGui.QTransform()) is None:
                self._current_rect_item = QtWidgets.QGraphicsRectItem()
                self._current_rect_item.setBrush(QtCore.Qt.red)
                self._current_rect_item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)
                self.addItem(self._current_rect_item)
                self._start = event.scenePos()
                r = QtCore.QRectF(self._start, self._start)
                self._current_rect_item.setRect(r)
            super(GraphicsScene, self).mousePressEvent(event)
    
        def mouseMoveEvent(self, event):
            if self._current_rect_item is not None:
                r = QtCore.QRectF(self._start, event.scenePos()).normalized()
                self._current_rect_item.setRect(r)
            super(GraphicsScene, self).mouseMoveEvent(event)
    
        def mouseReleaseEvent(self, event):
            self._current_rect_item = None
            super(GraphicsScene, self).mouseReleaseEvent(event)
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            scene =GraphicsScene(self)
            view = QtWidgets.QGraphicsView(scene)
            self.setCentralWidget(view)
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 好吧,我想做类似问题 44468775 你之前回答的问题,但是在一个场景中,并在我单击或双击后添加尽可能多的矩形或任何内容(我想构建类似简单的东西图)/我刚刚在 github 中检查了你的 github repo diagram-scene,但它有点重,我需要更简单的东西来理解 :) (对不起,烦人)
    • 就是这样,并且可以根据需要添加任意数量,这个 squeleton 将非常有帮助(几乎必须有 tuto)。同意你的 github repo 很大,只需要在里面导航。 Qt doc 通常用 C++ 编写,而对于像我这样的非程序员来说,用 python 进行翻译并不是那么容易。无论如何感谢您的回答
    猜你喜欢
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多