[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