[PyQt] QWidget 'destroyed' signal: possible regression?
Phil Thompson
phil at riverbankcomputing.com
Sun Mar 4 13:49:55 GMT 2012
On Sun, 26 Feb 2012 16:23:26 +0100, Pierre Raybaut
<pierre.raybaut at gmail.com> wrote:
> Hi Phil,
>
> I recently found out that a feature succesfully tested with older
> versions of PyQt was broken
> (http://code.google.com/p/spyderlib/issues/detail?id=951) and at the
> same time the Matplotlib developers contacted me for a similar issue
> (https://github.com/matplotlib/matplotlib/issues/711).
>
> To explain our problem, I wrote this test script:
>
>
#-----------------------------------------------------------------------------
> from PyQt4.QtGui import QApplication, QWidget
> from PyQt4.QtCore import Qt
>
> def print_from_function():
> print "Callback = Function"
>
> class TestWidget(QWidget):
> def __init__(self, parent=None):
> QWidget.__init__(self, parent)
> self.destroyed.connect(print_from_function)
> self.destroyed.connect(self.print_from_method)
> self.destroyed.connect(self.print_from_static_method)
> self.destroyed.connect(lambda:
self.print_from_lambda_function())
> self.setAttribute(Qt.WA_DeleteOnClose)
>
> def print_from_method(self):
> print "Callback = method"
>
> @staticmethod
> def print_from_static_method(self):
> print "Callback = static method"
>
> def print_from_lambda_function(self):
> print "Callback = lambda function"
>
> app = QApplication([])
> widget = TestWidget()
> widget.show()
> app.exec_()
>
#-----------------------------------------------------------------------------
>
> The issue with the test script above is that all callbacks connected
> to the 'destroyed' signal are triggered except for the callback which
> is a method (bound to the object to be destroyed).
>
> So the question is: is this a regression from PyQt v4.8.5? (or earlier)
First off I think that connecting the destroyed() signal to a method of
the object being destroyed is a bug. There are no guarantees about the
state of the object when the signal is emitted.
The change in behaviour was introduced in SIP v4.10.3 released July 2010.
As far as I can tell the change was made because I thought it was a good
idea rather than in response to a bug report. The intent would have been to
eliminate any "C/C++ object has been deleted" exceptions - but, as in this
case, the slot may not make any calls that would trigger an exception.
With hindsight I think I will back out the change. I dislike the
inconsistency in behaviour more than I dislike the buggy application code.
Phil
More information about the PyQt
mailing list