[PyKDE] How to detect if an object has been deleted
dmiller
dmiller at tcwcomputers.com
Mon Sep 18 14:26:16 BST 2006
Thanks Giovanni!
~ Daniel
On Sep 18, 2006, at 9:16 AM, Giovanni Bajo wrote:
> 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