[PyKDE] How to detect if an object has been deleted
Giovanni Bajo
rasky at develer.com
Mon Sep 18 14:16:54 BST 2006
Daniel wrote:
> Is there a documented way to detect if the underlying object has been
> deleted? Here's a short example that works, but it feels a bit dirty:
>
> def is_deleted(obj):
> try:
> obj.name
> except RunTimeError, ex:
> if str(ex) == "underlying C/C++ object has been deleted":
> return True
> raise
> return False
>
> There are obvious problems with this solution:
>
> - it depends on the exception message
> - it depends on an unrelated interface to produce the error (i.e.
> "name" must be a non-overridden member on the underlying object)
I'd use the following:
def is_deleted(obj):
import sip
try:
sip.unwrapinstance(obj)
except RuntimeError:
return True
return False
For PyQt (QObject), calling a simple function (like name(), or parent()) and
catching RuntimeError (that is, without caring of the error message) is
enough. I have succesfully used this method to implement "qtweakref", which
uses the actual lifetime of the C++ object instead of that of the Python
wrapper.
qtweakref.py:
===============================================================
from qt import *
import weakref
class qtref(weakref.ref):
__slots__ = "_callback",
def __new__(typ, o, callback=None):
if not isinstance(o, QObject):
wr = weakref.ref.__new__(weakref.ref, o, callback)
wr.__init__(o, callback)
return wr
wr = weakref.ref.__new__(typ, o)
if callback is not None:
wr._callback = lambda: callback(wr)
QObject.connect(o, SIGNAL("destroyed()"), wr._callback)
return wr
def __call__(self, *args, **kwargs):
o = super(qtref, self).__call__(*args, **kwargs)
if o is None:
return None
try:
o.parent()
except RuntimeError:
return None
return o
def __repr__(self):
o = self()
if o is not None:
return "<qtweakref at %08X; to '%.50s' at %08X>" % (id(self),
type(o).__name__, id(o))
return "<qtweakref at %08X; dead>" % id(self)
===============================================================
>>> from qt import *
>>> import qtweakref as weakref
>>> qApp = QApplication([])
>>>
>>>
>>>
>>> a = QObject(None)
>>> r = weakref.ref(a)
>>> r
<qtweakref at 2E2048A0; to 'QObject' at 2E2014F8>
>>> a.deleteLater()
>>> qApp.processEvents()
>>> r
<qtweakref at 2E2048A0; dead>
>>> a
<qt.QObject object at 0x2E2014F8>
>>>
>>>
>>>
>>> a = QObject(None)
>>> def cb(wr):
... print "dead:", wr
...
>>> r = weakref.ref(a, cb)
>>> a.deleteLater()
>>> qApp.processEvents()
dead: <qtweakref at 2E204870; dead>
--
Giovanni Bajo
More information about the PyQt
mailing list