This repository has been archived by the owner on Apr 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreceiver.py
64 lines (51 loc) · 2.23 KB
/
receiver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from types import MethodType
class _receiver_data(object):
sender = None
sigids = None
class receiver(object):
"""A descriptor which wrapps signal connect and disconnect for a single
object (the sender). Signal handlers may be registered with the
add_handler() method, after which point the handler will be automatically
connected when the property value is set. Prior to connecting new signal
handlers, old handlers are disconnected."""
def __init__(self, setter=None):
object.__init__(self)
self.handlers = {}
self.setter = setter
def __get__(self, instance, blah):
if hasattr(instance, "_receiver_data"):
return instance._receiver_data[self].sender
return None
def __set__(self, instance, value):
if not hasattr(instance, "_receiver_data"):
instance._receiver_data = {}
if not instance._receiver_data.has_key(self):
instance._receiver_data[self] = _receiver_data()
instance._receiver_data[self].sigids = {}
rd = instance._receiver_data[self]
# explicitly check for None, because sometimes valid instances have a
# False truth value. We don't want to forget to disconnect any signals,
# and at the same time we don't want to fail to connect a valid
# instance of, say, an empty container.
if rd.sender != None:
for id in rd.sigids.itervalues():
instance._receiver_data[self].sender.disconnect(id)
rd.sender = None
rd.sigids = {}
if value != None:
for sig, hdlr in self.handlers.iteritems():
rd.sigids[sig] = value.connect(sig, MethodType(hdlr,
instance))
rd.sender = value
if self.setter:
self.setter(instance)
def add_handler(self, signal, handler):
self.handlers[signal] = handler
def handler(property, signal):
"""A decorator which registers a given function as a signal handler for
the signal <signal> of object <property>. Property should be a receiver
object created with receiver()."""
def __handler__(func):
property.add_handler(signal, func)
return func
return __handler__