wxPython and MVC

Hi Mark,

The controller must know something about the view, so it can update the view according to the model.
However I'm not sure with the "stub" thing you wrote. What's the good out of that? Why can't we just bind some function in the controller as event handlers?

Cheers,
Harry Pan

···

2007/12/3, Mark Erbaugh mark@microenh.com:

I’m trying to develop applications along the lines of
model-view-controller design.

I think the frame class is the view portion. However, the event handling
routines are part of the controller. How do people separate them?

What I’ve been doing is writing “stub” event handlers for each event
that basically just pass the event off to a controller object, if one
exists.

in view

def onClick(self, event):

if self.controller:
    self.controller.onClick(self, event)

in controller

def onClick(self, view, event):
# here view gives the controller access to the view object
# (GUI frame instance)

Is there a better way?

Also, my concept of the controller is that it is independent of the
mechanism used to provide the GUI, so I don’t want to import wx into it.
That means that sometimes end up writing more code in the GUI. For

example, if the controller needs to display a dialog box, I have a
method in the GUI frame to do that. The controller can then access the
dialog using this method on the GUI frame. It gets the GUI frame’s

instance as the first parameter of its event handling code.

Thanks,
Mark


To unsubscribe, e-mail:
wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Harry,

Thanks for the reply. After reading more about wxPython event handling,
I'm experimenting with that approach now and it looks like it may work.
I agree that the controller will have to know something about the view
so I added a 'view' data member to the controller object. However, the
controller object only accesses specific methods in the view object, it
doesn't directly access wxPython features.

For example, to populate a wxListBox, the controller would call a method
view.setListBox(data). The method in the view class would then call the
appropriate wxPython method (or methods) to populate the list box.

This way, if I would ever use a different GUI object, such as a
web-based interface, it would only have to implment a setListBox(data)
method and I could use the same controller. Ideally, the same program
could run with a desktop interface with wxPython, or even Tkinter) or a
web-based interface.

Mark

···

On Mon, 2007-12-03 at 11:32 +0800, Pan Xingzhi wrote:

Hi Mark,

    The controller must know something about the view, so it can
update the view according to the model.
    However I'm not sure with the "stub" thing you wrote. What's the
good out of that? Why can't we just bind some function in the
controller as event handlers?

Cheers,
    Harry Pan

2007/12/3, Mark Erbaugh <mark@microenh.com>:
        I'm trying to develop applications along the lines of
        model-view-controller design.
        
        I think the frame class is the view portion. However, the
        event handling
        routines are part of the controller. How do people separate
        them?
        
        What I've been doing is writing "stub" event handlers for each
        event
        that basically just pass the event off to a controller object,
        if one
        exists.
        
        # in view
        def onClick(self, event):
            if self.controller:
                self.controller.onClick(self, event)
        
        # in controller
        def onClick(self, view, event):
            # here view gives the controller access to the view object
            # (GUI frame instance)
        
        Is there a better way?
        
        Also, my concept of the controller is that it is independent
        of the
        mechanism used to provide the GUI, so I don't want to import
        wx into it.
        That means that sometimes end up writing more code in the GUI.
        For
        example, if the controller needs to display a dialog box, I
        have a
        method in the GUI frame to do that. The controller can then
        access the
        dialog using this method on the GUI frame. It gets the GUI
        frame's
        instance as the first parameter of its event handling code.
        
        Thanks,
        Mark

Mark,

Normally people regard things like wx widgets and web pages as view. What you're doing is adding another abstract layer between controller and view (the 'view' data member in the controller object), so ideally you may change the view without affecting the controller. However, in most cases the controller is allowed to be coupled with view (maybe except for the web development, where view and controller may not even reside on the same machine). Think about this: even if you apply the 'view' data member, you still have to modify it if you change the UI from wx to web. So is it really necessary to encapsulate this modification in this 'view' data member rather than just modifying the controller?

That depends on how much you need on changing the face of your software ;-) But my suggestion is, don't overdo it. A lot of people tend to invent "imaginary requirement" and then find themselves devoting 80% effort on 20% (or less) of the functionalities.

You don't even need to make controller an object. Python doesn't force this, neither does wx. In my opinion, a set of functions in a Python module is enough. My point is that, the controller rarely has its own state, and its job is to manipulate model and view rather than providing APIs to change itself. OO gains little benefits here.

Cheers,
Harry Pan

···

2007/12/3, Mark Erbaugh mark@microenh.com:

On Mon, 2007-12-03 at 11:32 +0800, Pan Xingzhi wrote:

Hi Mark,

The controller must know something about the view, so it can

update the view according to the model.
However I’m not sure with the “stub” thing you wrote. What’s the

good out of that? Why can’t we just bind some function in the
controller as event handlers?

Cheers,
Harry Pan

2007/12/3, Mark Erbaugh <
mark@microenh.com>:
I’m trying to develop applications along the lines of
model-view-controller design.

    I think the frame class is the view portion. However, the
    event handling
    routines are part of the controller.  How do people separate
    them?

    What I've been doing is writing "stub" event handlers for each
    event
    that basically just pass the event off to a controller object,
    if one
    exists.


    # in view
    def onClick(self, event):
        if self.controller:
            self.controller.onClick(self, event)

    # in controller
    def onClick(self, view, event):
        # here view gives the controller access to the view object
        # (GUI frame instance)

    Is there a better way?

    Also, my concept of the controller is that it is independent
    of the
    mechanism used to provide the GUI, so I don't want to import
    wx into it.
    That means that sometimes end up writing more code in the GUI.
    For
    example, if the controller needs to display a dialog box, I
    have a
    method in the GUI frame to do that. The controller can then
    access the
    dialog using this method on the GUI frame. It gets the GUI
    frame's
    instance as the first parameter of its event handling code.
    Thanks,
    Mark

Harry,

Thanks for the reply. After reading more about wxPython event handling,
I’m experimenting with that approach now and it looks like it may work.

I agree that the controller will have to know something about the view
so I added a ‘view’ data member to the controller object. However, the
controller object only accesses specific methods in the view object, it

doesn’t directly access wxPython features.

For example, to populate a wxListBox, the controller would call a method
view.setListBox(data). The method in the view class would then call the
appropriate wxPython method (or methods) to populate the list box.

This way, if I would ever use a different GUI object, such as a
web-based interface, it would only have to implment a setListBox(data)
method and I could use the same controller. Ideally, the same program

could run with a desktop interface with wxPython, or even Tkinter) or a
web-based interface.

Mark

Harry,

Thank you for your comments. You have given me somethings to think
about.

    Normally people regard things like wx widgets and web pages as
view. What you're doing is adding another abstract layer between
controller and view (the 'view' data member in the controller object),
so ideally you may change the view without affecting the controller.
However, in most cases the controller is allowed to be coupled with
view (maybe except for the web development, where view and controller
may not even reside on the same machine). Think about this: even if
you apply the 'view' data member, you still have to modify it if you
change the UI from wx to web. So is it really necessary to encapsulate
this modification in this 'view' data member rather than just
modifying the controller?

In this design, the 'view' data member is simply a reference to the
wxFrame instance. The methods that store and retrieve data from the
wxFrame instance are just members of that object.

    That depends on how much you need on changing the face of your
software :wink: But my suggestion is, don't overdo it. A lot of people
tend to invent "imaginary requirement" and then find themselves
devoting 80% effort on 20% (or less) of the functionalities.

A very good point. I have a tendency to over-engineer things and to
spend too much time creating an elegant solution to something that never
becomes a problem.

    You don't even need to make controller an object. Python doesn't
force this, neither does wx. In my opinion, a set of functions in a
Python module is enough. My point is that, the controller rarely has
its own state, and its job is to manipulate model and view rather than
providing APIs to change itself. OO gains little benefits here.

Something to think about. I had assumed that the controller would keep
track of the current record and implement calls to a generic model
object. There would be only one instance of the model for a given screen
regardless of the number different instances of the same screen (each
with its own controller instance).

Thanks again,
Mark

···

On Mon, 2007-12-03 at 12:59 +0800, Pan Xingzhi wrote: