Hi List, taking the risk of annoying people by asking again, (I didn't get a response last time) I would like to kindly ask if the following behavior is really intended for PyQt4:
If a QObject is not used anymore, it gets deleted by Qt, and eventually garbage collected some time later. In the meantime, however, PyQt4 still delivers signals to the object, leading to a RuntimeError, since the C++ object is already deleted. C++ has the standard behaviour that upon deletion of an object, all signals automatically get disconnected. This is very useful, since I (as a programmer) don't need to care about this anymore. So, if this intended behaviour, how do I go about it? Sure, I could write a try:...except RuntimeError: around every method that I use as a slot, but that's some pain. If that was directly implemented in PyQt4, it would be much simpler: a simple if statement that checks if a QObject is still C++-alive before delivering signals would do the job. I also cannot see any drawbacks: since the receiving object cannot do much anymore anyway, given that its object has been deleted, I cannot imagine that anyone depends on the current behaviour. I re-send the code that shows the problem, I just tested it with PyQt 4.7.3 under Python 2.6 and Windows XP. Note that the garbage collection at the very end does make a difference, which it should never do, since it happens at random intervals and is thus not reliable (all of which is intended behaviour). Greetings Martin ------------------------ snip ---------------------------- from PyQt4.QtCore import QObject, SIGNAL, QCoreApplication import gc # following two lines not important from sys import argv app = QCoreApplication(argv) class A(QObject): def __init__(self, p=None): QObject.__init__(self, p) def g(self): self.emit(SIGNAL("sig")) def k(self): self.emit(SIGNAL("kill")) def f(self): try: print self.children() # only to test if C++ object is still alive except RuntimeError: print "hey, caught runtime error!" def kill(self): self.setParent(None) a = A() b = A(a) c = A(b) b.connect(a, SIGNAL("sig"), c.f) b.connect(a, SIGNAL("kill"), b.kill) a.g() # deliver signal to c, all fine c.v = c # create cycle to prevent immediate collection b = None c = None a.k() # now c ceases existence in the C++ world print "here" a.g() # signal is still delivered print "now collect" gc.collect() a.g() # signal no more delivered, python object has died ---------------------------------------- snip ----------------------------- _______________________________________________ PyQt mailing list PyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt