QWidget is not removed with the parent window

Using the code below, the __del__ method of my Preview widget is never called. If I uncomment the line " del window ", this will happen. Why?

 #!/usr/bin/env python from PyQt4 import QtGui class Preview(QtGui.QWidget): def __init__(self, parent): QtGui.QWidget.__init__(self, parent) def __del__(self): print("Deleting Preview") class PreviewWindow(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.widget = Preview(self) self.setCentralWidget(self.widget) def __del__(self): print("Deleting PreviewWindow") if __name__ == "__main__": app = QtGui.QApplication(["Dimension Preview"]) window = PreviewWindow() window.show() app.exec() # del window 
+4
source share
1 answer

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 
+2
source

Source: https://habr.com/ru/post/1379397/


All Articles