[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