[PyQt] (PyQt5) QGraphicsRectItem container is not destroyed
Justin Iurman
justin.iurman at uliege.be
Wed Jul 18 01:58:20 BST 2018
Actually, I've reduced the problem to a simple QGraphicsItem. This test gives me the same result:
""" Add a node to the scene """
node = QGraphicsRectItem()
self.scene.addItem(node)
print(sip.isdeleted(node))
print(sip.ispyowned(node))
sip.dump(node)
""" Remove the node from the scene """
self.scene.removeItem(node)
print(sip.isdeleted(node))
sip.dump(node)
Here is the output:
(before deletion)
False
False
<PyQt5.QtWidgets.QGraphicsRectItem object at 0x7fd38a6141f8>
Reference count: 3
Address of wrapped object: 0x15c2050
Created by: Python
To be destroyed by: C/C++
Parent wrapper: <PyQt5.QtWidgets.QGraphicsScene object at 0x7fd38a5fba68>
Next sibling wrapper: <__main__.Host object at 0x7fd38a614dc8>
Previous sibling wrapper: NULL
First child wrapper: NULL
(after deletion)
False
True
<PyQt5.QtWidgets.QGraphicsRectItem object at 0x7fd38a6141f8>
Reference count: 2
Address of wrapped object: 0x15c2050
Created by: Python
To be destroyed by: Python
Parent wrapper: NULL
Next sibling wrapper: NULL
Previous sibling wrapper: NULL
First child wrapper: NULL
> Hi everyone,
>
> Here is the context:
>
> - a QWidget (Node > QLabel) is added to a QGraphicsScene
> - a QGraphicsProxyWidget is returned, embedding the QWidget
> - a movable container (NodeContainer > QGraphicsRectItem) wraps up the proxy
>
> Simplified hierarchy (parent -> child): container -> proxy -> node.
>
> container = NodeContainer()
> self.scene.addItem(container)
>
> proxy = self.scene.addWidget(node)
> proxy.setParentItem(container)
>
> So far, so good. Anyway, when it comes down to removing a node, I just noticed
> that both the proxy and the node are deleted as expected, while the container
> is not. Here is deletion part:
>
> proxy = node.graphicsProxyWidget()
> container = proxy.parentItem()
>
> self.scene.removeItem(proxy)
> self.scene.removeItem(container)
>
> node.deleteLater()
> proxy.deleteLater()
>
> I know that some instructions may be useless because of some others. I just
> wanted to make sure I tried every possible way to delete each part.
>
> Do you have an idea of why the container is not destroyed ?
>
> Debug hint: running sip.isdeleted(container) on the container shows False and
> the object is still reachable. When running sip.delete(container) then again
> sip.isdeleted(container) it now shows True (and it is not reachable anymore,
> obviously). Also checked with sys.getrefcount(container).
>
> Also, when running
>
> print(sip.ispyowned(container))
> print(sip.dump(container))
>
> 1) before deletion
>
> False
> <__main__.NodeContainer object at 0x7f9b6cf44af8>
> Reference count: 3
> Address of wrapped object: 0x19d9610
> Created by: Python
> To be destroyed by: C/C++
> Parent wrapper: <PyQt5.QtWidgets.QGraphicsScene object at 0x7f9b6cf41f78>
> Next sibling wrapper: <__main__.Link object at 0x7f9b6cf44798>
> Previous sibling wrapper: <__main__.Host object at 0x7f9b6cf449d8>
> First child wrapper: <PyQt5.QtWidgets.QGraphicsProxyWidget object at
> 0x7f9b6cf44c18>
>
> 2) after deletion
>
> True
> <__main__.NodeContainer object at 0x7f9b6cf44af8>
> Reference count: 2
> Address of wrapped object: 0x19d9610
> Created by: Python
> To be destroyed by: Python
> Parent wrapper: NULL
> Next sibling wrapper: NULL
> Previous sibling wrapper: NULL
> First child wrapper: NULL
>
> One can see that the container is now owned by Python after deletion. Why ?
> Thanks,
>
> Justin
More information about the PyQt
mailing list