[PyQt] Again, problems with garbage collection
Martin Teichmann
lkb.teichmann at gmail.com
Fri Mar 19 11:27:59 GMT 2010
Hi List, Hi Phil,
>> I just upgraded to PyQt4 4.7.2 (with Python 2.6.4 on Windows XP)
>> and the following little script crashes with "unterlying C/C++ object
>> has been deleted"
>>
>> I guess that's a bug.
>
> Why? It works as I would expect.
Oops. I didn't realize that that's a excpected behaviour. I was under the
impression that Qt shouldn't "own" objects and delete them, so that
this runtime error was always indicator of a bug (or an indicator that
someone forgot to call the parent's __init__, maybe the error message
should actually read "underlying C/C++ object has been deleted or not
yet created", anyhow, that's not the current problem)
Unfortunately, this leads to the somewhat annoying behaviour that
signals are still sent to C++-dead but python-alive objects. That's
especially annoying when the python object ought to be dead already,
just had not been collected yet, as illustrated in the following
example. Note how gc.collect makes a difference, a situation that
better should not happen as garbage collection happens at random intervals...
Greetings
Martin
And here the example:
---------------------- 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 -----------------------------------------
More information about the PyQt
mailing list