[PyQt] QWidget 'destroyed' signal: possible regression?

Pierre Raybaut pierre.raybaut at gmail.com
Sat Mar 10 22:48:34 GMT 2012


Well, you're quite merciless with my amateur programming skills...

Anyway, thanks for taking the time to take care of it. For what it's
worth, I prefer a rough exception than a silent fail. So your
conclusion is fine with me.

-Pierre

Le 4 mars 2012 à 14:49, Phil Thompson <phil at riverbankcomputing.com> a écrit :

> 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