Simplifying PyGTK signals in Python
This is a followup to my previous post.
A fairly common pattern in GTK code seems to be updating a widget whenever a value changes in your controller. That is, something like this:
__gsignals__ = {
'counter-changed': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (int,)),
}
def __init__(self):
self.counter = 0
def inc(self):
self.counter += 1
self.emit('counter-changed', self.counter)
def dec(self):
self.counter -= 1
self.emit('counter-changed', self.counter)
Needless to say, this can get a bit tedious. With a bit of stack frame hackery we can reduce that boilerplate to the following:
counter = SignalProperty('counter-changed', 0)
def inc(self):
self.counter += 1
def dec(self):
self.counter -= 1
Here's the code:
def __init__(self, name, default=None):
self.name = name
self.default = default
frame = sys._getframe(1)
locals_ = frame.f_locals
signals = locals_.setdefault('__gsignals__', {})
signals[name] = (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (object,))
def __get__(self, instance, owner):
if instance is None:
return self
return getattr(instance, '_signal_' + self.name, self.default)
def __set__(self, instance, value):
setattr(instance, '_signal_' + self.name, value)
instance.emit(self.name, value)
Comments [0]