首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除QGraphicsItem的父项

删除QGraphicsItem的父项
EN

Stack Overflow用户
提问于 2012-11-15 14:30:01
回答 1查看 1.4K关注 0票数 2

我有一个名为child_itemQGraphicsItem,它是另一个名为parent_itemQGraphicsItem的子级。我需要将child_itemparent_item中分离出来,这样child_item就没有父级了。

但是当我尝试childItem.setItemParent(None)时,我的脚本崩溃了。

显然,这是因为当您以这种方式删除QGraphicsItem的父项时,该项目将返回到Qt...

现在,我刚刚创建了一个global_parent QGraphicsItem,所以如果有任何项目需要取消父级,我只需要在global_parent下将其设置为父级,如果QGraphicsItem具有父global_parent,我的代码将表现得像没有父级一样,但我希望有一个更好的解决方案。

有什么想法吗?

我的一些代码:

代码语言:javascript
复制
POINT_SIZE = 7
class Test_Box(QGraphicsItem):
    # Constants
    WIDTH           = 50 * POINT_SIZE
    HEIGHT          = 13 * POINT_SIZE
    RECT            = QRectF(0, 0, WIDTH, HEIGHT)
    CORNER_RADIUS   = 1.5 * POINT_SIZE


    def __init__(self, position, parent=None):
        super(Test_Box, self).__init__(parent)

        # Settings
        self.setFlags(  self.flags()                            |
                        QGraphicsItem.ItemIsSelectable          |
                        QGraphicsItem.ItemIsMovable             |
                        QGraphicsItem.ItemIsFocusable           |
                        QGraphicsItem.ItemSendsScenePositionChanges )
        self.setPos(position)


    def boundingRect(self):
        return Test_Box.RECT


    def paint(self, painter, option, widget):
        # Draw Box
        brush   = QBrush()
        painter.setBrush(brush) 
        painter.drawRoundedRect(Test_Box.RECT, Test_Box.CORNER_RADIUS, Test_Box.CORNER_RADIUS)



    def itemChange(self, change, variant):
        super(Test_Box, self).itemChange(change, variant)
        if change == QGraphicsItem.ItemScenePositionHasChanged:
            self.setParentItem(None)
        return QGraphicsItem.itemChange(self, change, variant)

但是,调用setItemParent并将该项的父项设置为另一项确实有效,因此我同时使用泛型父项。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-15 20:09:21

如果setParent不是拼写错误,那么这就是您的问题。QGraphicsItem没有setParent方法,这应该会给您一个错误。您应该使用setParentItem

代码语言:javascript
复制
children.setParentItem(None)

编辑

我基于你的项目创建了一个测试用例:

代码语言:javascript
复制
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

POINT_SIZE = 7
class Test_Box(QGraphicsItem):
    # Constants
    WIDTH           = 50 * POINT_SIZE
    HEIGHT          = 13 * POINT_SIZE
    RECT            = QRectF(0, 0, WIDTH, HEIGHT)
    CORNER_RADIUS   = 1.5 * POINT_SIZE


    def __init__(self, position, parent=None):
        super(Test_Box, self).__init__(parent)

        # Settings
        self.setFlags(  self.flags()                            |
                        QGraphicsItem.ItemIsSelectable          |
                        QGraphicsItem.ItemIsMovable             |
                        QGraphicsItem.ItemIsFocusable           |
                        QGraphicsItem.ItemSendsScenePositionChanges )
        self.setPos(position)


    def boundingRect(self):
        return Test_Box.RECT


    def paint(self, painter, option, widget):
        # Draw Box
        brush   = QBrush()
        painter.setBrush(brush) 
        painter.drawRoundedRect(Test_Box.RECT, Test_Box.CORNER_RADIUS, Test_Box.CORNER_RADIUS)



    def itemChange(self, change, variant):
        super(Test_Box, self).itemChange(change, variant)
        if change == QGraphicsItem.ItemScenePositionHasChanged:
            self.setParentItem(None)
        return QGraphicsItem.itemChange(self, change, variant)


class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.scene = QGraphicsScene()

        self.item1 = Test_Box(QPointF(0, 0))
        self.item2 = Test_Box(QPointF(20, 20))
        self.item11 = Test_Box(QPointF(10, 5), self.item1)

        self.scene.addItem(self.item1)
        self.scene.addItem(self.item2)

        self.view = QGraphicsView(self.scene)

        self.listItems = QPushButton('list')
        self.listItems.clicked.connect(self.printItems)

        layout = QHBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(self.listItems)
        self.setLayout(layout)

    def printItems(self):
        for item in self.scene.items():
            print item, item.parentItem()


app = QApplication(sys.argv)

w = Window()
w.show()

sys.exit(app.exec_())

它像预期的那样工作,但我确实发现了一些奇怪的行为。如果我没有在Window类中保留对项的引用,即,如果我执行以下操作,那么当我移动项时,应用程序就会崩溃。

代码语言:javascript
复制
class Window(QWidget):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.scene = QGraphicsScene()

        item1 = Test_Box(QPointF(0, 0))
        item2 = Test_Box(QPointF(20, 20))
        item11 = Test_Box(QPointF(10, 5), item1)

        self.scene.addItem(item1)
        self.scene.addItem(item2)

        self.view = QGraphicsView(self.scene)

        self.listItems = QPushButton('list')
        self.listItems.clicked.connect(self.printItems)

        layout = QHBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(self.listItems)
        self.setLayout(layout)

    def printItems(self):
        for item in self.scene.items():
            print item, item.parentItem()

我实际上不知道发生了什么,但看起来这些项目是垃圾回收的,这不应该发生,因为addItem会将所有权交给scene,这应该会让这些项目“存活”。这可能是PyQt中的一个错误,但我不确定。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13392555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档