[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