[PyQt] Re: Virtual methods and an extra reference
Sundance
sundance at ierne.eu.org
Mon Jun 23 14:13:05 BST 2008
Phil wrote:
> I will look at this properly when I have the time.
Thank you, Phil -- it's appreciated.
In the meanwhile, for those who may come across this thread in the
future, here's a working workaround (as opposed to the almost-working-
but-not-quite one from earlier *g*):
1) Rename the problematic methods, for instance by putting an underscore
in front: paintEvent() becomes _paintEvent().
2) In your object's constructor, add such a line as:
s.paintEvent = WeakCallable( s._paintEvent )
3) Add somewhere the following code:
---[ Code ]------------------------------------------------------------
import new
from weakref import ref, ReferenceError
class WeakCallableRef:
def __init__( s, fn, callback=None ):
assert callable( fn )
s._methname = None
s._objref = None
s._fnref = None
s._dead = False
s._callback = callback
obj = getattr( fn, "im_self", None )
if obj: ## fn is a bound method
s._objref = ref( obj, s.markDead )
s._fnref = ref( fn.im_func, s.markDead )
s._class = fn.im_class
else: ## fn is a static method or a plain function
s._fnref = ref( fn, s.markDead )
def markDead( s, ref ):
if not s._dead:
s._dead = True
if s._callback: s._callback( s )
def __call__( s ):
if s._dead: return None
if s._objref: ## bound method
fn = s._fnref()
obj = s._objref()
if None not in ( fn, obj ):
return new.instancemethod( fn, obj, s._class )
else:
return s._fnref()
class WeakCallable:
def __init__( s, fn ):
s._ref = WeakCallableRef( fn )
def __call__( s, *args, **kwargs ):
fn = s._ref()
if fn: return fn( *args, **kwargs )
raise ReferenceError( "Attempted to call dead WeakCallable %s!" \
% s )
-----------------------------------------------------------------------
... And you should be good.
The above aggregates the feedback from this thread -- thank you,
Kevin! -- into one neat, reasonably simple if generally loathesome
workaround.
Goodness, how I hate workarounds.
-- S.
More information about the PyQt
mailing list