[PyQt] Mis-transfer in QLayout.addWidget
Martin Teichmann
martin.teichmann at gmail.com
Tue Jul 8 08:58:00 BST 2014
Hi Phil, Hi List,
QLayout and most of its sub-classes have a method addWidget
that add a widget to the layout. Within the sip specification,
the widget parameter is declared /Transfer/, meaning that the
ownership of the widget is transferred to the layout. Unfortunately,
Qt transfers the ownership to the parent widget of the layout,
not the layout itself. This is unfortunate, because once the layout
is deleted, the widget might be garbage collected as well, while
the parent widget still holds a reference to it. This leads to the
weird situation of a python-created widget to loose all its python
attributes.
I added a script that illustrates the problem. It raises and
AttributeError in the very last line, which should not be there.
Greetings
Martin Teichmann
-------- test script follows ------
from PyQt4.QtGui import QLayout, QApplication, QWidget, QHBoxLayout
from PyQt4.QtCore import pyqtSignal, pyqtSlot
from functools import partial
import gc
import sys
app = QApplication([])
class Widget(QWidget):
sig = pyqtSignal()
@pyqtSlot()
def slot(self):
print 'SLOT', self.bla
def slat(self, x):
print 'SLAT', self.bla
parent = QWidget()
w = Widget(parent)
w.bla = 'b'
ws = Widget(parent)
ws.sig.connect(w.slot)
Widget(w).sig.connect(partial(w.slat, 3)) # keep w alive
layout = QHBoxLayout()
parent.setLayout(layout)
# the parent is a referrer
assert w.parent() in gc.get_referrers(w)
layout.addWidget(w)
# the parent still should be referrer, but is not
# assert w.parent() in gc.get_referrers(w) # assert will fail
# a workaround looks as follows:
#w.setParent(parent)
layout.setParent(None)
del layout
del w
# the following lines illustrate the problem
# the first signal emission works well,
# the second raises an AttributeError
ws.sig.emit()
gc.collect()
ws.sig.emit()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20140708/04ef1a30/attachment.html>
More information about the PyQt
mailing list