Python Qgraphicscene和QGraphicsItem处理程序

Python Qgraphicscene和QGraphicsItem处理程序,python,pyqt5,qgraphicsscene,qgraphicsitem,Python,Pyqt5,Qgraphicsscene,Qgraphicsitem,我是Qt的新手,特别是PyQt5。我正在尝试使用QGraphicsView、Qgraphicscene和QGraphicsPixmapItem开发GUI。我的目标是在用户单击场景时向场景添加项目(在QGraphicscene子类中使用mousePressedEvent()实现),并且使用mouseMoveEvent()可以移动元素 然后,我发现,通过我的实现,这些项可以像从边界矩形外“推”它们一样移动。因此,为了修复它,经过一些搜索之后,我决定实现QGraphicsPixmapItem的一个子类

我是Qt的新手,特别是PyQt5。我正在尝试使用QGraphicsView、Qgraphicscene和QGraphicsPixmapItem开发GUI。我的目标是在用户单击场景时向场景添加项目(在QGraphicscene子类中使用mousePressedEvent()实现),并且使用mouseMoveEvent()可以移动元素

然后,我发现,通过我的实现,这些项可以像从边界矩形外“推”它们一样移动。因此,为了修复它,经过一些搜索之后,我决定实现QGraphicsPixmapItem的一个子类来实现它自己的事件函数

尽管如此,我发现我的物品不能识别mousePressed或mouseMove事件,只能识别QGraphicscene中的事件。我的问题是:

  • 在没有遇到第一个问题的情况下移动元素的最有效方法是什么
  • 是否可以合并场景和项目事件处理程序?我还没有完全理解事件传播
  • 为了更清楚,我在下面留下了关于移动问题的代码:

    #!/usr/bin/env python3
    
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    import sys
    
    
    class GraphicsScene(QGraphicsScene):
        def __init__(self):
            super(GraphicsScene, self).__init__()
            self.image = 'car.png' # Image of your own
            self.inserted = False
    
        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton and not self.inserted:
                img = QPixmap(self.image).scaled(50, 50, Qt.KeepAspectRatio)
                pixmap = QGraphicsPixmapItem(img)
                offset = pixmap.boundingRect().topLeft() - pixmap.boundingRect().center()
                pixmap.setOffset(offset.x(), offset.y())
                pixmap.setShapeMode(QGraphicsPixmapItem.BoundingRectShape)
                pixmap.setFlag(QGraphicsItem.ItemIsSelectable, True)
                pixmap.setPos(event.scenePos())
                super().mousePressEvent(event)
                self.addItem(pixmap)
                self.inserted = True
            else:
                pass
    
        def mouseMoveEvent(self, event):
            super().mouseMoveEvent(event)
            item = self.itemAt(event.scenePos(), QTransform())
            if item is None:
                return
    
            orig_cursor_position = event.lastScenePos()
            updated_cursor_position = event.scenePos()
            orig_position = item.scenePos()
    
            updated_cursor_x = updated_cursor_position.x() - orig_cursor_position.x() + orig_position.x()
            updated_cursor_y = updated_cursor_position.y() - orig_cursor_position.y() + orig_position.y()
            item.setPos(QPointF(updated_cursor_x, updated_cursor_y))
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super(QMainWindow, self).__init__()
            self.resize(600, 600)
            self.canvas = QGraphicsView()
            self.scene = GraphicsScene()
            self.setCentralWidget(self.canvas)
            self.canvas.setScene(self.scene)
    
        def showEvent(self, event):
            self.canvas.setSceneRect(QRectF(self.canvas.viewport().rect()))
    
        def resizeEvent(self, event):
            self.canvas.setSceneRect(QRectF(self.canvas.viewport().rect()))
    
    
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())
    

    我认为OP是不必要的复杂,因为QGraphicsSiteMs(如QGraphicsPixmapItem)已经实现了此功能,只剩下激活QGraphicsSiteMs::ItemIsMovable标志:

    class GraphicsScene(QGraphicsScene):
        def __init__(self):
            super(GraphicsScene, self).__init__()
            self.image = "car.png"  # Image of your own
            self.inserted = False
    
        def mousePressEvent(self, event):
            super().mousePressEvent(event)
            if event.button() == Qt.LeftButton and not self.inserted:
                img = QPixmap(self.image).scaled(50, 50, Qt.KeepAspectRatio)
                pixmap = QGraphicsPixmapItem(img)
                pixmap.setOffset(-pixmap.boundingRect().center())
                pixmap.setShapeMode(QGraphicsPixmapItem.BoundingRectShape)
                pixmap.setFlag(QGraphicsItem.ItemIsSelectable, True)
                pixmap.setFlag(QGraphicsItem.ItemIsMovable, True)
                pixmap.setPos(event.scenePos())
                self.addItem(pixmap)
                self.inserted = True
    

    重写mouseMoveEvent是不必要的。

    请提供@eyllanesc。为了更好地理解,我对问题进行了编辑。谢谢该代码不是MRE,请阅读链接。尝试在
    pixmap=QGraphicsPixmapItem(img)
    @eyllansc之前添加
    super().mousePressedEvent(event)
    ,我已经重写了代码,希望现在一切正常(这是我在这里的第一篇帖子;感谢您的帮助)。此外,我添加了您的线路,但仍然无法正常工作。谢谢您的帮助!它工作得很好。我以为在活动中不需要super()!