If the QObject subclass has a parent, then Qt will remove it when the parent is removed. On the other hand, if a QObject subclass does not have a parent, it will (eventually) be removed using python.
Hope this example makes it a little clearer:
from PyQt4 import QtGui class Widget(QtGui.QWidget): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) self.destroyed.connect(self.handleDestroyed) def __del__(self): print ('__del__:', self) def handleDestroyed(self, source): print ('destroyed:', source) class Foo(Widget): def __init__(self, parent): Widget.__init__(self, parent) class Bar(Widget): def __init__(self, parent): Widget.__init__(self, parent) class Window(Widget): def __init__(self, parent=None): Widget.__init__(self, parent) self.foo = Foo(self) self.bar = Bar(None) if __name__ == "__main__": app = QtGui.QApplication([__file__, '-widgetcount']) window = Window() window.show() app.exec_()
What outputs:
__del__: <__main__.Window object at 0x88f514c> destroyed: <__main__.Foo object at 0x88f5194> __del__: <__main__.Bar object at 0x88f51dc> Widgets left: 0 Max widgets: 4
EDIT
Secondly, it seems that there may be a bug (or at least a difference in behavior) with some versions of PyQt4.
As a possible workaround, it seems that creating two python names for the main widget and then explicitly deleting each of them can help eliminate both sides of the C ++ and python object.
If the following line is added to the script:
tmp = window; del tmp, window
Then the output will be:
__del__: <__main__.Window object at 0x8d3a14c> __del__: <__main__.Foo object at 0x8d3a194> __del__: <__main__.Bar object at 0x8d3a1dc> Widgets left: 0 Max widgets: 4
source share