Package rats :: Module sig
[hide private]
[frames] | no frames]

Source Code for Module rats.sig

 1  #!/usr/bin/env python 
 2  """ 
 3  File:    signal.py 
 4  Author:  Thiago Marcos P. Santos 
 5  Created: August 28, 2008 
 6   
 7  Purpose: A signal/slot implementation 
 8  Source: http://code.activestate.com/recipes/576477/ 
 9   
10  A Signal calls all the callbacks registered in its slots whenever it state  
11  changes.  
12  """ 
13   
14  from weakref import WeakValueDictionary 
15   
16 -class Signal(object):
17 """ 18 A Signal is callable. When called, it calls all the callables in its slots. 19 """
20 - def __init__(self):
21 self._slots = WeakValueDictionary()
22
23 - def __call__(self, *args, **kargs):
24 for key in self._slots: 25 func, _ = key 26 func(self._slots[key], *args, **kargs)
27
28 - def connect(self, slot):
29 """ 30 Slots must call this to register a callback method. 31 :param slot: callable 32 """ 33 key = (slot.im_func, id(slot.im_self)) 34 self._slots[key] = slot.im_self
35
36 - def disconnect(self, slot):
37 """ 38 They can also unregister their callbacks here. 39 :param slot: callable 40 """ 41 key = (slot.im_func, id(slot.im_self)) 42 if key in self._slots: 43 self._slots.pop(key)
44
45 - def clear(self):
46 """ 47 Clears all slots 48 """ 49 self._slots.clear()
50 51 if __name__ == "__main__": 52 # Sample usage:
53 - class Model(object):
54 - def __init__(self, value):
55 self._value = value 56 self.changed = Signal()
57
58 - def set_value(self, value):
59 self._value = value 60 self.changed() # Emit signal
61
62 - def get_value(self):
63 return self._value
64
65 - class View(object):
66 - def __init__(self, model):
67 self.model = model 68 model.changed.connect(self.model_changed)
69
70 - def model_changed(self):
71 print("New value: %s" % (self.model.get_value()))
72 73 model = Model(10) 74 view1 = View(model) 75 view2 = View(model) 76 view3 = View(model) 77 78 model.set_value(20) 79 del view1 # remove one listener 80 model.set_value(30) 81 model.changed.clear() # remove all listeners 82 model.set_value(40) 83 84 # To disconnect : 85 # model.changed.disconnect(view1.model_changed) 86