将其父项添加到QGraphicsScene后创建Qt子项使其无法移动

时间:2017-03-29 20:51:54

标签: python qt qt5 pyqt5

如果您向QtWidgets.QGraphicsEllipseItem添加QGraphicsScene,则该广告是可移动的。 如果您将其指定为QtWidgets.QGraphicsItemGroup作为父级,则将父级添加到场景中,它是移动的。

如果在添加子项之前将父项添加到场景中,它将变为不可移动。为什么呢?

以下是一个独立的示例。如果您运行代码,您会注意到您可以创建四个Point,所有这些都是移动的,然后在第五个Point上添加其父级后,它将变为不动。在Qt4中情况并非如此。

from PyQt5.QtWidgets import (QApplication, QGraphicsView,\                      
                             QGraphicsScene, QGraphicsItem)
from PyQt5 import QtWidgets, QtGui, QtCore

class Point(QtWidgets.QGraphicsEllipseItem):
    def __init__(self, pos):
        super(Point, self).__init__(0,0,10,10)
        self.setPos(pos)
        self.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable | \
                      QtWidgets.QGraphicsItem.ItemIsSelectable)

class Graphics(QGraphicsItem):
    def __init__(self):
        super(Graphics, self).__init__()
        self.numPoints = 0
        self.polygon = QtWidgets.QGraphicsItemGroup()

    def paint(self, painter, option, widget):
        pass

    def boundingRect(self):
        return QtCore.QRectF(0,0,300,300)

    def mousePressEvent(self, event):
        pos = event.pos()
        itemAt = self.scene().itemAt(pos, QtGui.QTransform())

        # If nothing is under the mouse, create a new point and accept the event
        if not isinstance(itemAt, Point):
            # Add the point to the scene and set its parent
            pt = Point(pos)
            pt.setParentItem(self.polygon)
            if pt.scene() is None:
                self.scene().addItem(pt)
            else:
                print "The item was implicitly added to the scene by its parent"

            # On the fifth point, add the polygon to the scene
            self.numPoints += 1
            if self.numPoints == 4:
                self.scene().addItem(self.polygon)

            event.accept()
        super(Graphics, self).mousePressEvent(event)

class MainWindow(QGraphicsView):
    def __init__(self):
        super(MainWindow, self).__init__()
        scene = QGraphicsScene(self)
        scene.addItem(Graphics())
        scene.setSceneRect(0, 0, 300, 300)
        self.setScene(scene)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    mainWindow = MainWindow()

    mainWindow.show()
    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:1)

来自文档:

  

QGraphicsItemGroup是一种特殊类型的复合项,它将自身及其所有子项视为一个项(即,所有子项的所有事件和几何都合并在一起)。当用户想要将几个较小的项目组合成一个大项目以简化项目的移动和复制时,在演示工具中使用项目组是很常见的。

由于Point(s)内的self.polygon被视为单个对象,因此该对象必须是Movable本身:

self.polygon.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True)

如果你想要你的"积分"在父母QGraphicsItemGroup内移动不是正确的选择,而是可以使用GraphicsRectItemQGraphicsPolygonItem和其他人