I hope this forum is the correct one to ask questions about Patrick's
dispatcher module ;-)
I'm using an old and slightly patched version of the dispatcher module
to 'connect' models to widgets in my program.
The model instances in my program trigger certain events by calling
dispatcher.send(signal=(self._name, "show"), visible=self._active)
The gui creates zero, one or more widgets which should display the
'state' of the model, and the the gui connects the widgets to the
models:
def on_create(self, widget):
name = widget.label
dispatcher.connect(signal=(name, "show"),
receiver=widget.show))
The above code arranges that the widget is made visible when the model
becomes active, and invisible when the model becomes inactive.
The above code works very well, I don't need to disconnect the widgets
from the model when they are destroyes, dispatcher does this
automatically with it's weak references.
The problem occurs when the event handling become more complicated, and
cannot simply be done by a simple (bound) method call in a widget
instance.
What I want to achive is something like this:
def on_create(self, widget):
name = widget.label
import registry
model = registry.get(name)
def handler(model, widget=widget):
data = model.get_some_data()
widget.show_value(data)
dispatcher.connect(signal=(name, "changed"),
receiver=handler)
In other words, the handler for the event must do an operation on the
model for some data, and then call a method on the widget. (The
'changed' event in the above code has the model as a parameter to make
this possible).
This code doesn't work, because when the the on_create method returns,
the handler function is destroyed, and dispatcher drops the connection.
One possibility would be to assign handler to widget as an attribute so
that its lifetime is the same as the widget, but this is ugly. And it
has a further consequence: because there is a reference cycle between
the handler function and the widget, the widget is not destroyed any
more (before the next gc.collect() run).
Equally ugly would be to make the handler function a method of the
widget class, because this would break the separation between the model and
the widget.
Any ideas, anyone? Is this a common problem?
Thanks,
Thomas
|