wxPython MVC working with GUI

1.6k views Asked by At

I have a working program in 1 class. I wish to convert it to MVC pattern.

I've implemented observer design as shown here and i opened 3 .py files for Model, View and Controller. I'm having trouble understanding what goes where.

For example: this code in the original class

    helpMenu = wx.Menu()
    helpMenu.Append(ID_ABOUT, "&About", "Display info")

    self.Bind(event=wx.EVT_MENU, handler=self.OnHelpAbout, id=ID_ABOUT)

...

def OnHelpAbout(self,e):
    title = self.GetTitle()
    d = wx.MessageDialog(self, "About " + title, title, wx.ICON_INFORMATION | wx.OK)
    d.ShowModal()
    d.Destroy()

This menu code lines should be in the View, and the function OnHelpAbout should be implemented in the Controler. But how do I call it? should I have an instance of the Controller in the View? Where do I sign for the observer? Also, if this function set a dialog = making changes in the view How do I do that? If I understood correctly I need to call another function in the View and put the code there?

I guess what i'm missing is a basic template to work with. I haven't found any source that explains how to do it with GUI & GUI Events.

1

There are 1 answers

1
nepix32 On BEST ANSWER

The MVC entry in the wxPython wiki gives a good insight how the spearation of concerns could look like. The first (newer) example leverages pypubsub, the older example at the bottom deals with wx.Events alone.

While it may or may not conform to the strict MVC paradigma, it shows beautifully how the model is separated form view and controller.

In your example the creation of the menu (the first two lines) would go into the view. The controller would hold the event method (OnHelpAbout) and do the binding on the menu item. For the model your example would have no code. The frame title could be kept in the controller and put into the frame on object creation/after creation.

UPDATE/EDIT1

This is no exact science and can get messy as already pointed out. How about the following:

view.py

class myframe(wx.Frame):
    def __init__(…
        # code for menu creation goes here
        self.helpmenu = …

controller.py

from view import myframe

class mycontroller(object):
    def __init__(self, app):
        self.title = 'mytitle'
        self.frame = myframe(…
        self.frame.SetTitle(self.title)

        self.frame.helpmenu.Bind(…, handler=self.OnHelpAbout, …)

        self.frame.Show()

    def OnHelpAbout(self, evt):
        title = self.title
        # show message dialog
        …

if __name__ == '__main__':
    app = wx.App(…
    ctrler = mycontroller(app)
    app.MainLoop()

Wake me if you manage to find a "pure" solution …