[PyQt] Memory leak
Phil Thompson
phil at riverbankcomputing.com
Sun Jul 6 17:29:00 BST 2008
On Sun, 06 Jul 2008 15:18:10 +0200, Giovanni Bajo <rasky at develer.com>
wrote:
> On Sat, 2008-07-05 at 23:04 +0100, Phil Thompson wrote:
>> 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.
>
> I believe that it's more correct if you fix this code not to have any
> memory leak.
I disagree, I don't work around Qt bugs in PyQt.
> Either that, or you get smarter wrt when the ownership is
> transferred from Python to C++ (that is, when the layout is reparented
> to a widget, if ever).
The reason I'm not going to do this is that it would break lots of code (at
least, lots of my code).
> And in any case, you should probably raise this
> issue with Trolltech (it's at least a documentation issue, I'd say).
Agreed.
> Anyway, it turns out that I had reduced the testcase a little too much:
> it was not the actual memory leak I was seeing in my application.
>
> The correct testcase is this one:
Fixed in tonight's SIP snapshot.
Phil
More information about the PyQt
mailing list