[wxpython-dev] Google SoC Project - MVC

Nitro nitro at dr-code.org
Thu May 29 23:56:22 PDT 2008


Am 30.05.2008, 07:41 Uhr, schrieb Kevin Ollivier <kevino at theolliviers.com>:

> Hi Peter,
>
> On May 29, 2008, at 1:57 AM, Peter Damoc wrote:
>
>> Hi Keith,
>>
>> My suggestion is to investigate Cells technology (pycells and
>> Trellis) integration with wxPython
>
> Definitely worth taking a look at, but I think a better approach would
> be to simply allow wxPython controls to take a model and controller,
> and use them when set. This way we're not trying to re-invent wxPython
> or trying to get fundamentally different frameworks with different
> design philosophies and target audiences to try and play nice
> together. We're just extending it to be MVC-friendly. We can use
> something like wx.lib.pubsub to send notifications when either the
> model or the view changes, and the controller sets up listeners for
> these events and handles any changes that needs made.

I am doing the same for FloatCanvas. Internally I wrote a little "event  
manager" which just wraps wx.lib.pubsub so it can be replaced with another  
implementation if desired. One of the problems I encountered while doing  
this is that topics are supposed to be only strings. This seems to be a  
problem, because if I want to subscribe only for the updates of a specific  
object it's not (cleanly) possible.

Doing something like

obj = createSomeModelWhichSendsEventsWhenItChanges()
Publisher().subscribe( (obj,), obj_all_messages_handler )
Publisher().subscribe( (obj, 'sizeChanged'), obj_size_changed_handler )

is not possible right now. Maybe you could set the topic to  
(str(id(obj)),), but that doesn't seem like a clean solution. I am also  
wondering whether this would work at all for the default wxPython objects,  
because you might get different objs for the same underlying C++ object.  
Of course not using any of these objects doesn't create the problem.

I can see three solutions:

1) Patch pubsub so that it allows non-strings to be used.
2) Don't make publisher a singleton. Instead use it something like

obj = createSomeModelWhichSendsEventsWhenItChanges()
obj.subscribe( '', obj_all_messages_handler )
obj.subscribe( 'sizeChanged', obj_size_changed_handler )

or

obj = createSomeModelWhichSendsEventsWhenItChanges()
obj.events.subscribe( '', obj_all_messages_handler )
obj.events.subscribe( 'sizeChanged', obj_size_changed_handler )

This also involves changing pubsub. Either you'd have to inherit from  
Publisher or create an attribute from Publisher or you inherit from a  
helper class that provides the same subscribe/sendMessage methods and  
forwards them to the global publisher by prepending (obj,) which is  
basically 1).

3) Use a third-party module like pydispatcher/louie  
( http://pydispatcher.sourceforge.net/ ). The advantage here is that  
pydispatcher seems quite robust to me (used it for years without issues)  
and pubsub doesn't look like it's used all that much and so there are  
probably still some bugs lurking. It also supports using arbitrary  
subscribers (not only functions that take a single argument) with keywords  
and arbitrary topics.
The disadvantages here is that it doesn't support something like a topic  
tree out of the box (though I think this is possible by connecting one  
event to an other via a function - so you could connect 'sports/baseball'  
to 'sports'). The whole thing also happens in a single module instead of a  
class, so there's only one pydispatcher for everything. The approach in 2)  
could be faked with it though (just make subscribe prepend (obj,) in front  
of the topic.
Maybe there are other observer/observable design pattern implementations  
in python which I am not familiar with and which could be useful here.

What's your opinion on solving this?

-Matthias


More information about the wxpython-dev mailing list