1
from types import MethodType
4
class _receiver_data(object):
10
class receiver(object):
12
"""A descriptor which wrapps signal connect and disconnect for a single
13
object (the sender). Signal handlers may be registered with the
14
add_handler() method, after which point the handler will be automatically
15
connected when the property value is set. Prior to connecting new signal
16
handlers, old handlers are disconnected."""
18
def __init__(self, setter=None):
23
def __get__(self, instance, blah):
24
if hasattr(instance, "_receiver_data"):
25
return instance._receiver_data[self].sender
28
def __set__(self, instance, value):
29
if not hasattr(instance, "_receiver_data"):
30
instance._receiver_data = {}
31
if not self in instance._receiver_data:
32
instance._receiver_data[self] = _receiver_data()
33
instance._receiver_data[self].sigids = {}
34
rd = instance._receiver_data[self]
36
# explicitly check for None, because sometimes valid instances have a
37
# False truth value. We don't want to forget to disconnect any signals,
38
# and at the same time we don't want to fail to connect a valid
39
# instance of, say, an empty container.
41
for sid in rd.sigids.itervalues():
42
instance._receiver_data[self].sender.disconnect(sid)
45
if not (value is None):
46
for sig, hdlr in self.handlers.iteritems():
47
rd.sigids[sig] = value.connect(sig, MethodType(hdlr,
53
def add_handler(self, signal, hdlr):
54
self.handlers[signal] = hdlr
57
def handler(prop, signal):
59
"""A decorator which registers a given function as a signal handler for
60
the signal <signal> of object <property>. Property should be a receiver
61
object created with receiver()."""
63
def __handler__(func):
64
prop.add_handler(signal, func)