Re-factoring for the MVC pattern - doubts about sharing vision from the controller

I am trying to reorganize my application (with 1000+ GUI lines) into an MVC style template. Logical code is already separated from the graphical interface, so this is not a problem. I am worried about sharing a look with the controller. I understand the basic principle of MVC and this tutorial in the wxpython wiki was very useful, but the sample code is a little simplified and leaves me with when I try to apply the principal to my own project, which is quite difficult.

A fragment of the structure.

I have MainWindow with a number of widgets, including noteBook (tab), noteBook has several tabs, one of the tabs (which I call FilterTab ) contains two instances of the class (which I call FilterPanel ), which is a list box, three buttons, one to clean, one to delete and one to add items to / from the list. Depending on the flags passed to the class when creating the event instance, the add buttons can create various types of dialog boxes, for example, a text input dialog box or a Picker directory, etc.

Here is just one part of the GUI that is pretty layered - with event handlers buried in the FilterPanel class.

If I were to convert this part to MVC, I would have to bind button events for each FilterPanel instance in my controller (and not in the filterPanel class) - in this case there are two filterPanel instances

So, I will have something similar for each button (3 buttons on the number of filters * Panel instances of the panel) plus handlers.

  self.mainWindow.filterTab.dirFilterPnl.Bind(wx.EVT_BUTTON, self.onAdd_dirFilterPnl, self.mainWindow.filterTab.dirFilterPnl.addBtn, self.mainWindow.filterTab.dirFilterPnl.addBtn.GetId() ) 

Which adds a lot of extra code (doubles the number of event handlers if I only have two filterPanel instances)

So I like to know if I'm right?

+6
python user-interface model-view-controller wxpython
source share
2 answers

If I were to convert this part to MVC I would have to bind button events for each FilterPanel instance in my controller (and not in filterPanel)

Not necessary! The philosophy and practice of MVC does not imply that “views” are elementary widgets; your FilterPanel may well be considered / implemented as a "rich / composite" widget that generates its own "events" of a higher level (directed to the controller) and is updated accordingly. Thus, this composite widget can have handlers for lower-level “events” and synthesize higher-level events from them by sending them to the controller; the controller does not need to know or care about each button, etc., namely, events with a higher abstraction that it receives, such as "the user wants to select a directory for target X" or "the user wants to enter text for target Y", - and answer them, telling what to do.

The key point is that the view does not make "semantic" decisions based on the events that it processes, and never sends any command to the model - the controller is an indispensable "intermediary" for all such interactions.

For an analogy, keep in mind that the lowest GUI level has very low level events, such as “left mouse button down” and “left mouse button up” - “button panel widget” responds directly to them, changing the appearance of the button (“visual” solution rather than “strategic”), and ultimately, if and when necessary, an event with a higher abstraction is synthesized, such as “button click” (when a mouse button is clicked without an intermediate mouse movement, invalid, for example click hypothesis). The latter is then sent to any higher level to “respond” to button presses.

Likewise, your rich / composite widgets can accept such events and synthesize higher abstractions that the controller should respond to. (The same abstract event can be triggered by pressing a button, selecting a menu, certain keystrokes ... the controller does not care about these "visual" lower-level considerations, that the work of the view / widget and the view / widget does not contain hard " strategic "decisions and actions for such user interactions that the task of the controller).

Separation of problems helps with problems such as testing and application flexibility; this is not unheard of, because such advantages can be bought at a price when there is still some alternative code where everything is hardcoded ... but if you choose MVC, you mean that the price is worth the price.

wx may not be an ideal basis for implementing this, but you can subclass wx.Event - or you can use a separate event system, such as pydispatcher, for events with higher abstraction that flow between the individual subsystems to separate the controller from a specific choice GUI I usually use Qt, whose signal / slot model, IMNSHO, expands / scales better than regular GUI event systems. But this is a different choice and a different problem.

+9
source share

wxPython includes a pubsub that follows the Publish / Subscribe methodology. This is similar to pydispatcher, although their implementation is different. The wxPython wiki contains some examples of how to use pubsub in your program, as well as this simple tutorial on the topic:

http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/

The MVC in the GUI is not quite the same as in Django or TurboGears. I find that I can put most of my logic into controllers and in my "view", I just get attached to the controller. Something like that:

view.py

btn.Bind (wx.EVT_BUTTON, self.onButton)

def onButton (self, event): controller.someMethod (* args, ** kwargs)

Depending on what the calculation is, I can start the stream from my controller and post the result later using wx.CallAfter + pubsub.

+1
source share

All Articles