[PyQt] deleteLater vs removeItem on a QGraphicsObject

oliver oliver.schoenborn at gmail.com
Tue Dec 6 21:02:19 GMT 2016


I posted on stackoverflow
<http://stackoverflow.com/questions/41004665/deletelater-vs-removeitem-on-a-qgraphicsobject>
but perhaps posting here will reach additional folks:

When we want to dispose of a QGraphicsItem object in our scene, we call
scene.removeItem(item). When we want to dispose of a QGraphicsObject object
in our scene, we call scene.removeItem(item) because it derives from
QGraphicsItem, but we ALSO call item.deleteLater() because it derives from
QObject and that is the recommended way of disposing of QObjects (so that
pending signals to and from the item are properly handled).

PROBLEM is that slots in the object item can get called AFTER the item has
been removed from the scene, due to how deleteLater() functions. This
requires that we test for self.scene() being None in slots. But it is easy
to forget to do that, and forgetting this can lead to exception when slot
is called, so sometimes it will work fine because the slot didn't call
anything on scene and then poof, some day some if block in slot calls the
scene and you get an exception, not very nice for the end-user.

Another approach is to not call deleteLater() before removing the item from
the scene, but this requires manually disconnecting the item from other
objects. This has similar disadvantage to testing for self.scene() being
None in slots, and its easy to forgot to disconnect a slot.

A better way of mitigating this source of error (if there are no hidden
gotchas) would be to NOT call scene.removeItem(item) when item is a
QGraphicsObject, and JUST call its deleteLater(): it *seems*, based on some
simple tests, that the scene automatically removes item from its list when
it eventually gets destroyed. HOWEVER, I can't find any Qt documentation
that states this, and I might have just been lucky in my tests; perhaps in
a more realistic scenario I would get a memory leak or a crash.

So I'm leaning towards calling deleteLater() without calling removeItem()
when item is a QGraphicsObject, but do you think this is safe?

-- 
Oliver
My StackOverflow contributions
My CodeProject articles
My Github projects
My SourceForget.net projects
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20161206/b53b5926/attachment.html>


More information about the PyQt mailing list