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


_______________________________________________
PyKDE mailing list    [email protected]
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde

Reply via email to