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

Erik Janssens Erik.Janssens at conceptive.be
Sun Mar 11 10:48:44 GMT 2012


Hello Pierre, Phil,

I'm not so sure the current behavior is inconsistent.  One
of the reasons of using signal/slot over normal callbacks is
that they are disconnected when one of the objects gets
deleted.

So if you connect the destroyed signal to a non-QObject-method, the
slot is called.  If you connect it to a QObject-method that has
been deleted, the slot is not called.  

The destroyed signal is emitted in the destructor of QObject.  So in
case of a QWidget, this after the QWidget destructor has done its work.
After this has been done, any call to a QWidget method might crash the
application.

I would prefer the behavior to be consistent with C++ Qt (although
I don't know what that exactly is)

The documentation of Qt states that the destroyed signal should be
used to monitor a QObject, I don't think its intended to serve
as a kind of destructor.

It's worth thinking this through before changing it...

Regards,

Erik

On Sat, 2012-03-10 at 23:48 +0100, Pierre Raybaut wrote:
> 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
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt




More information about the PyQt mailing list