PyQt中的QGraphicsItem何时被销毁?

2024-09-28 22:23:08 发布

您现在位置:Python中文网/ 问答频道 /正文

似乎QGraphicsItem状态从To be destroyed by: C/C++变为{},但没有被销毁,仍然可以访问。这是预期的行为吗?如果是这样,有人能解释吗?在

创作部

node = QGraphicsRectItem()
self.scene.addItem(node)

print("Deleted ? ", sip.isdeleted(node))
print("Owned by Python ? ", sip.ispyowned(node))
sip.dump(node)

输出

^{pr2}$

删除部分

self.scene.removeItem(node)

print("Deleted ? ", sip.isdeleted(node))
print("Owned by Python ? ", sip.ispyowned(node))
sip.dump(node)

输出

Deleted ?  False
Owned by Python ?  True
<PyQt5.QtWidgets.QGraphicsRectItem object at 0x7fcdb82371f8>
    Reference count: 2
    Address of wrapped object: 0x214bf80
    Created by: Python
    To be destroyed by: Python
    Parent wrapper: NULL
    Next sibling wrapper: NULL
    Previous sibling wrapper: NULL
    First child wrapper: NULL

可以看到,删除后它现在归Python所有。它仍然存在。为什么?在


Tags: toselfnodebybescenewrappernull
2条回答

add the item to the scene, Qt takes ownership of it时,这样就不需要在Python端保留对它的显式引用。这意味着,当场景被删除时,该项目的C++部分也将被删除,如果没有其他引用保存到Python部分,它也将被垃圾收集(因此将没有剩下任何东西)。在

当你remove the item from the scene, ownership passes back to the caller时,谁现在全权负责删除它。如果^ {CD1> }继承了^ {< CD2> },可以调用^ {< CD3}}来删除C++部分-但是这仍然会留给您空的Python包装器,所以它不会有太大的差别。在

删除PyQt包装器的方法与删除任何其他python对象的方法相同,即使用del,或者简单地让它超出范围并允许以正常方式进行垃圾回收。没有特殊的PyQt方法来删除这些对象,因为不需要任何特殊的方法。在

正如你所期望的那样,sip中的任何信息都不会被你完全删除。在

<>最后,注意,可以始终独立于PyQT包装器删除C++部分。如果您这样做,然后尝试访问项的方法,您将得到一个RuntimeError

>>> scene = QGraphicsScene()
>>> node = QGraphicsRectItem()
>>> scene.addItem(node)
>>> del scene
>>> node.rect()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QGraphicsRectItem has been deleted

更新

下面是一个演示,演示了当项目从场景中移除并允许超出范围时,如何对其进行垃圾回收。当然,如果其他地方有对该项目的引用(即如果ref count>;1),则不会删除该项目。在

^{pr2}$

输出:

Deleted ?  False
Owned by Python ?  True
<PyQt5.QtWidgets.QGraphicsRectItem object at 0x7f90f66d5798>
    Reference count: 3
    Address of wrapped object: 0x205bd80
    Created by: Python
    To be destroyed by: Python
    Parent wrapper: NULL
    Next sibling wrapper: NULL
    Previous sibling wrapper: NULL
    First child wrapper: NULL

gc collect...
deleted

删除后不要让它超出范围。它从所有Qt中删除,但是Python仍然有您用来引用项的node变量。在

相关问题 更多 >