[PyQt] Memory leak

Phil Thompson phil at riverbankcomputing.com
Sat Jul 5 23:04:49 BST 2008


On Thu, 03 Jul 2008 16:04:42 +0200, Giovanni Bajo <rasky at develer.com>
wrote:
> Hi Phil,
> 
> with SIP 4.7.6, PyQt 4.2.2, Qt 4.4.0:
> 
> ========================================
> import sip
> import weakref
> from PyQt4.Qt import *
> 
> class MyWidget(QWidget):
>      def sizeHint(self):
>          return QSize(900, 700)
> 
> app = QApplication([])
> 
> ws = MyWidget(None)
> wr = weakref.ref(ws)
> 
> L = QVBoxLayout(None)
> L.addWidget(ws)
> L.activate()
> del L
> del ws
> 
> import gc
> gc.collect()
> 
> assert wr() is None
> ========================================
> 
> The assert triggers, meaning that the object of type MyWidget is not 
> released.

This appears to be a Qt problem. Although the docs say that a layout takes
ownership of the widget when addWidget() is called it leaves the
destruction of the widget to the eventual owner of the layout and doesn't
call the widget's dtor itself.

If the layout is never used (ie. never passed as an argument to
QWidget.setLayout()) then all the widgets in the layout will leak.

An equivalent C++ version behaves in the same way.

I could change addWidget() so that the layout doesn't take ownership of the
widget (ie. to match the implementation rather than the documentation) but
that will break any code that creates a populated layout and returns it
from a function.

Phil



More information about the PyQt mailing list