[wxpython-dev] Google SoC Project - MVC

Mike Rooney mxr at qvii.com
Fri May 30 12:17:05 PDT 2008


Robin Dunn wrote:
> Kevin Ollivier wrote:
>> 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'm not sure how to go about implementing this, but some thoughts I've 
> had about MVC in wxPython are that it would be nice to be able to have 
> some sort of modular controller and/or model.  In other words, each 
> widget involved in the view would have an associated component that 
> would automatically integrate itself into a composite controller or 
> model of some sort.  Then there would be a standard but flexible way 
> to hook that to the application's model.  This would allow the app 
> model to be whatever it needs to be for the app or the programmer's 
> preferences, and just use a flexible but well defined interface for 
> communicating with the rest of the system, which was all built 
> automatically based on how the UI is put together.
>
>

Yes, I have been trying to brainstorm something like this for one of my 
projects. To me the most elegant solution is a model, view, and 
controller which can each exist independently and don't need any of the 
other parts.

So you can have a View (wxPython app), say a contact list, that allows 
you to add, edit, and remove entries. The View knows what boxes to pop 
up, how to add entries to the View's list when you click Add, etc. When 
"changes" occur (whatever ultimately requires an updated Model), you 
just use pubsub like pubsub.Publisher().sendMessage("CONTACT ADDED", 
('Bob', '755-555-1212', 'bob at aol.com')), or something like that. The 
View doesn't care if anything is listening. The controller can pick up 
on this, and make the appropriate model calls. Without a controller, 
there is just no data persistence.

When the View launches it would send a pubsub message, informing anyone 
that may be listening that it can be populated with information. Now if 
a controller is there, it could iterate over its contacts, sending the 
identical messages ("CONTACT ADDED", ('Bob', '755-555-1212', 
'bob at aol.com')), and the View knows the appropriate way to represent 
that contact.

You can also import the controller from a command-line and manually call 
whatever functions the controller binds to the appropriate pubsub 
messages (addContact(self, Name, Phone, Email)), (or you could do it 
with pubsub :) without a need for the View.

Using a solution like this and using pubsub, you can have multiple Views 
for the same data and multiple Models storing the data in completely 
different ways, without any extra work at all. You have all these 
components just announcing occurrences, and anything that wants to act 
on it can do so in the way it defines as useful.

In less abstract words (from my blueprint at  
https://blueprints.launchpad.net/wxbanker/+spec/proper-mvc): "Have the 
GUI and the controller send the same messages when the same action is 
performed, with unique IDs created by the generator. Each component 
maintains a list of uIDs to ignore, and a uID is added to it either when 
it has already responded to it or has generated it itself. For example, 
the user removes an account in the GUI. The GUI sends ("ACCOUNT 
REMOVED", (uID, accountNum)). The Controller receives this, realizes IT 
didn't generate the message (based on the uID), and acts on it. It then 
sends the same message (with the same ID). The GUI will ignore it, since 
it sent it and has already done the appropriate GUI things. The 
Controller will also ignore this message since it will have added the ID 
to its "sent" list as well."

So one way to accomplish better MVC in Python would to wrap pubsub in a 
way which allows each component to send messages in a standard way, and 
handling the aforementioned situations so each thing only responds to 
the message once, and making this transparent to the user.

Note all of this isn't strict MVC. To do it strictly (or as strict as 
you can in wxPython) you would have to Bind all wxPython events directly 
to the controller's appropriate functions. But this requires a 
controller which not only knows details about the View, but a View that 
REQUIRES an underlying controller. I don't see this as being 
particularly elegant or useful.

Okay, sorry for the long post, but I wanted to contribute my ideas and 
ideally get some feedback as well.

Thanks for reading, if you made it this far!
- Mike Rooney


More information about the wxpython-dev mailing list