[PyQt] QWidget not deleted with its parent window

Phil Thompson phil at riverbankcomputing.com
Fri Nov 4 04:17:10 GMT 2011

On Thu, 3 Nov 2011 19:49:03 -0400, Tavian Barnes
<tavianator at tavianator.com> wrote:
> I originally posted this on stackoverflow[1], where I learned that
> this seems to be a bug in PyQt 4.8.6.  (I'm using Qt 4.7.4 if that's
> relevant.)
> Basically, the __del__ method of the central widget of a window is
> never called.  Example:
> #!/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
> If I uncomment the "del window" line, "Deleting Preview" prints as
> expected.  Otherwise, I just see "Deleting PreviewWindow".  Apparently
> pyqt 4.8.5 works correctly.
> [1]

It's not a bug, just a (subtle) change in (undefined) behaviour. Without
the explicit "del window" the objects are being destroyed as part of the
interpreter shutdown and in an unpredictable order. This is the common
cause of crashes on program exit. To help avoid this SIP v4.13 (it's not
PyQt) prevents any Python reimplementations of C++ methods (and also
__del__) from being called once the interpreter starts to shutdown. The
surprise, if any, is why PreviewWindow.__del__ is being called.

Basically any program that relies on specific behaviour after the
interpreter starts to shutdown is buggy. Also I would never use __del__
anyway because of its impact on the cyclic garbage collector.


More information about the PyQt mailing list