From: Thomas H. <th...@py...> - 2003-07-25 17:00:00
|
(This is a repost of a mail sent to the pycrust users list, Patrick told me about this dispatcher list. BTW: dispatcher is a great module, and I wish you well with the sf project. But expect further questions or usage reports from me, I have at least one.) 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 frame creates zero, one or more widgets which should display the 'state' of the model, and the frame 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? Thomas |