Separating GUI code from Logic

828 views
Skip to first unread message

Tony Cappellini

unread,
Sep 19, 2011, 7:45:34 PM9/19/11
to wxpytho...@googlegroups.com
It's been a while since I used wx, so I wanted to refresh my memory
on pubsub and mvc architecture.

After looking through the wiki, I found this


http://wiki.wxpython.org/SeparateGuiAndLogic

There is saw a short wx program that contains something I've never seen before.

In this class
class AppFrame( wx.Frame ) :

there is a line which instantiates a class to handle the gui events
# Must call before any event handler is referenced.

self.eventsHandler = EventsHandler( self )


I like this idea of separating the event handlers into their own
class.

Is this considered a good way to structure a wx program?

Are there any pitfalls with this architecture?


Thanks

siris phi

unread,
Sep 20, 2011, 2:23:52 AM9/20/11
to wxpytho...@googlegroups.com
Interesting. putting such a class inside the AppFrame doesn't really separate the gui and the event logic. Maybe a subclass of wx.App would be a better, but then the event binding becomes even more removed from the widgets they bind to, which is prone to the development of bald spots on one's head in my xp. 

I think I may try to do something like this. Looking at the code, EventHandler as a class could even be generated at runtime from a config file, database, or metaclass, which would make alot more sense than all this self.Bind(wx.WHATEVER, self.OnWhatever) we write over and over and over....





--
<i>godspeed you black cats</i>

Robin Dunn

unread,
Sep 21, 2011, 11:55:15 AM9/21/11
to wxpytho...@googlegroups.com

The only separating it does is move the code to a new class. It does
not reduce coupling at all as the EventsHandler still needs to know
about the structure and nature of the UI. In a true separation of the
GUI and logic in the OOP sense the program logic would not need to know
anything about the UI at all, perhaps other than there are certain
capabilities that can be triggered by sending messages to it. Pubsub or
similar tools are helpful for implementing things like that.


--
Robin Dunn
Software Craftsman
http://wxPython.org

oliver

unread,
Sep 22, 2011, 11:52:21 PM9/22/11
to wxpytho...@googlegroups.com
On Wed, Sep 21, 2011 at 11:55 AM, Robin Dunn <ro...@alldunn.com> wrote:
On 9/19/11 4:45 PM, Tony Cappellini wrote:
It's been a while since I used wx, so I wanted to refresh my memory
on pubsub and mvc architecture.

After looking through the wiki, I found this

http://wiki.wxpython.org/SeparateGuiAndLogic

...

Is this considered a good way to structure a wx program?

The only separating it does is move the code to a new class.  It does not reduce coupling at all as the EventsHandler still needs to know about the structure and nature of the UI.  In a true separation of the GUI and logic in the OOP sense the program logic would not need to know anything about the UI at all, perhaps other than there are certain capabilities that can be triggered by sending messages to it.  Pubsub or similar tools are helpful for implementing things like that.

Tony,
Oliver 

Kevin Ollivier

unread,
Sep 23, 2011, 12:02:02 PM9/23/11
to wxpytho...@googlegroups.com
Hi Robin,

On Sep 21, 2011, at 8:55 AM, Robin Dunn wrote:

> On 9/19/11 4:45 PM, Tony Cappellini wrote:
>> It's been a while since I used wx, so I wanted to refresh my memory
>> on pubsub and mvc architecture.
>>
>> After looking through the wiki, I found this
>>
>>
>> http://wiki.wxpython.org/SeparateGuiAndLogic
>>
>> There is saw a short wx program that contains something I've never seen before.
>>
>> In this class
>> class AppFrame( wx.Frame ) :
>>
>> there is a line which instantiates a class to handle the gui events
>> # Must call before any event handler is referenced.
>>
>> self.eventsHandler = EventsHandler( self )
>>
>>
>> I like this idea of separating the event handlers into their own
>> class.
>>
>> Is this considered a good way to structure a wx program?
>
> The only separating it does is move the code to a new class. It does not reduce coupling at all as the EventsHandler still needs to know about the structure and nature of the UI.

MVC is about separation of concerns though, not reducing coupling throughout all code. In MVC, the controller (in this example, EventsHandler) is coupled to both the view and the model. That is, it knows the structure and nature of both of them. The important part, though, is that the view doesn't know the structure and nature of the model, and vice-versa.

Technically, the above example still does break that by assigning the controller by subclassing wx.Frame (so AppFrame knows and references the controller), but it could be alternatively done as follows, in someplace such as OnInit:

self.frame = wx.Frame(...)
self.eventsHandler = EventsHandler(self.frame)

In any case, moving your event handlers into a separate class definitely moves the code towards better MVC compliance. If you seriously doubt this, try it for a while and see. I think the real reason this approach feels wrong and doesn't jive with a lot of wx developers, is that it is anti-thema to wx design patterns, which have you putting tons of code in wx.Frame subclasses. Make no mistake, though, those wx.Frame subclasses really just handle sub-control initialization and handling of control events to manipulate GUI state, data structures, etc. It rarely ever is used to add new behaviors and capabilities to wx.Frame itself. When you think about the original design and purpose of subclassing, it was probably not to have classes like 'CarThatTakesMeToWork' as a subclass of Car that contains the logic of driving the roads to and from work. ;-) But that is, in practice, the sorts of classes most wx apps write.

> In a true separation of the GUI and logic in the OOP sense the program logic would not need to know anything about the UI at all, perhaps other than there are certain capabilities that can be triggered by sending messages to it. Pubsub or similar tools are helpful for implementing things like that.

Pubsub can help with separation of concerns, but this is not a given - the big question is, where are you putting your signal handlers? If your pubsub signal is sent to the GUI (e.g. wxFrame subclass), and then in that GUI object you're storing and manipulating app data, then you're still not truly separating concerns. Case in point, the PubSub example recently posted in this thread does exactly that.

Regards,

Kevin

>
> --
> Robin Dunn
> Software Craftsman
> http://wxPython.org
>

Tony Cappellini

unread,
Sep 23, 2011, 1:04:32 PM9/23/11
to wxpytho...@googlegroups.com, oliver.s...@gmail.com
Oliver,

I've used pubsub before, and I'm about to use it again in a current project.

In my post, I was referring to a wiki tutorial called "Separating GUI Code from Logic".
I just liked the idea of moving the event handlers to another class, to simplify clutter.

I really shouldn't have used "
Separating GUI Code from Logic" for the subject of my post,
because it took everyone down the wrong path.

But I'm grateful for everyone's input & advice.
It's always useful.

Thanks


oliver <oliver.s...@gmail.com>
Sep 22 11:52PM -0400 ^

 
> UI at all, perhaps other than there are certain capabilities that can be
> triggered by sending messages to it. Pubsub or similar tools are helpful
> for implementing things like that.
 

Kevin Ollivier

unread,
Sep 24, 2011, 3:35:13 PM9/24/11
to wxpytho...@googlegroups.com
Hi all,

On Sep 23, 2011, at 9:02 AM, Kevin Ollivier wrote:

> Hi Robin,
>
> On Sep 21, 2011, at 8:55 AM, Robin Dunn wrote:
>
>> On 9/19/11 4:45 PM, Tony Cappellini wrote:
>>> It's been a while since I used wx, so I wanted to refresh my memory
>>> on pubsub and mvc architecture.
>>>
>>> After looking through the wiki, I found this
>>>
>>>
>>> http://wiki.wxpython.org/SeparateGuiAndLogic
>>>
>>> There is saw a short wx program that contains something I've never seen before.
>>>
>>> In this class
>>> class AppFrame( wx.Frame ) :
>>>
>>> there is a line which instantiates a class to handle the gui events
>>> # Must call before any event handler is referenced.
>>>
>>> self.eventsHandler = EventsHandler( self )
>>>
>>>
>>> I like this idea of separating the event handlers into their own
>>> class.
>>>
>>> Is this considered a good way to structure a wx program?
>>
>> The only separating it does is move the code to a new class. It does not reduce coupling at all as the EventsHandler still needs to know about the structure and nature of the UI.
>
> MVC is about separation of concerns though, not reducing coupling throughout all code. In MVC, the controller (in this example, EventsHandler) is coupled to both the view and the model. That is, it knows the structure and nature of both of them. The important part, though, is that the view doesn't know the structure and nature of the model, and vice-versa.
>
> Technically, the above example still does break that by assigning the controller by subclassing wx.Frame (so AppFrame knows and references the controller), but it could be alternatively done as follows, in someplace such as OnInit:
>
> self.frame = wx.Frame(...)
> self.eventsHandler = EventsHandler(self.frame)
>
> In any case, moving your event handlers into a separate class definitely moves the code towards better MVC compliance. If you seriously doubt this, try it for a while and see.

BTW, sorry about how this sounds, it didn't really come out right. I do, however, feel this approach has more advantages than perhaps appear at first glance. I have in my own experience used the EventsHandler approach to separate code into reusable behaviors. (e.g. I once wrote a InlineTextSearchHandler which lets me pass in a searchCtrl and a wx.STC or wx.TextCtrl, and it provides inline search capabilities. With a little work, it could be extended for wx.RichTextCtrl, wx.WebView, etc.) So I know from experience the general approach does work and can be quite useful. You could do this sort of thing with a mixin too, but I personally find this approach to be cleaner, though perhaps that is just bikeshedding. Also, as a general practice, it decreases the amount of work needed to move from code specific to one purpose to reusable code. Some code you won't reuse, but often you don't know these things in advance, and having it 'ready to reuse' when you do need it is icing on the cake. :) It tends to lead to a Unix tool-like approach of building small, focused code modules instead of "just do everything in your wx.Frame subclass". If you've ever seen a 2000 line wx.Frame subclass (I have, and I've even written them! ;-), you can sort of see how this gets out of control.

This is actually where a lot of the raving about 'magic' in Cocoa comes from. It's not that you can do anything special with Obj-C that you can't do with other tools / languages, it's just that you find that this sort of approach of segmenting out behaviors into discrete chunks leads over time to being able to build apps more like "legos" than writing tedious code over and over. You actually get encouraged to be a bit more ambitious with your interfaces and such, because you will code it in a reusable way and start easily throwing advanced behaviors into all your controls quickly.

You can do that sort of thing with wx, but the default design patterns don't really encourage it. So adding reusability is an added upfront effort (much like you must layout your dialogs before you actually build them with sizers) - and that doesn't really jive with the modern, real world nature of coding where requirements are changing all the time and you need to provide quick turnaround. You may suddenly and quickly need reusability when you didn't before. To use a cliched (but perhaps apt) buzzword, it makes code more 'agile'.

Regards,

Kevin

Dev Player

unread,
Sep 25, 2011, 1:33:12 AM9/25/11
to wxpytho...@googlegroups.com
I thought I saw the MVP OOP pattern demo'd for wxPython to seperate object "interface" (ie event handlers). Although it's called MVP it was more like MVIP (an ancronmy I made up to show the way I saw the model demo'd) and the demo clumped the interface in with either the view or the presentation part of the pattern.
 
When I started learning Python, wxPython and messing around with the wxPython Demo by trying to make it more "plugable" some year or two or more back by trying to refractor it into this MVP pattern I discovered a few things (in my unexperienced point of view):
1. I was way out of my league.
2. Refactoring wxPython apps into another pattern is painful and counter to its originating source, that being wxPython >> wxwidgets  >> C++ Win SDK API ==>> underlying structure of what Microsoft showed us are the OSes structures. (left x-windows out for better clarity).
3. The original MVP author abandoned that pattern in favor of the Observer pattern.
4. Many of the well-performing intellegently-written public-domain-available-source-code apps/packages are not written using MVC, (ie wxPython Demo, Editra for example)
5. Microsoft and IBM claim they like the MVP pattern over the MVC pattern.
6. MVC and MVP patterns for small apps and the like are counter-Pythonic Zen.
7. it's really easy to misuse those patterns, even by pros, judging by all the topics and blogs posted over years about "how to do it".
 
What got me going down the path to research using MVP with wxPython in the first place? A lot of reasons really.
 
1. When I started looking on how to pattern my first Python projects, I didn't know what librarys or packages to trust (to be around for a long time and to be patched over a long time. I didn't know how committed the original authors, creators, contributors and the user base were committed to sustaining any GUI package, database package, networking library, etc. I didn't know what packages where too narrow or two broad, which ones where well documented or cryptic or nonexistant. Or which libraries or packages worked with other libraries and packages (twisted reactor vs. wxPython Mainloop vs Pand3d reactor, etc.).
 
And for another reason. Package and library version control is horrible in Python compared to less modern languages (imho). If I had downloaded tons of little libraries to patch together my apps, then when a new version of Python came out I was afraid I'd have to recreate that development environment for the new version from scratch, downloading and installing and configuring all those tiny little libraries again. There was talk of starting beta releases on Python 3.0 at the time. That's just messy. Also lots of little packages and libraries brings up complications in licencing usage.
 
So I wanted to make each component (ie "concern") replaceable, pluggable;
1. This seemed to mesh well with Python's encouragement of ducktyping,
2. allow for changing selected packages based on licensing at various points in app development,
3. allow selecting a package that's missing capabilities that are under development (beta) and soon to be released.
 
I wanted to be able to (and still do what it to be able to) replace Ogre3d with Pygame with Panda3d with Tinker if I had/wanted too without messing with how I had the data logic and it's interface. (ie seperation of concerns).
 
What I came up with was a pretty rediculus OOP model (because I'm not a good programmer), which was MVP-like
data --> data interface (ie the model) --> data/gui interface translator and primary process loop <-- gui interface (ie event handler) <-- gui
 
Which I broke down even further to be:
data <--> data interface <--> data stream flow controller <--> translator <--> gui loop (ie process) <--> gui interface (ie. methods/handlers) <--> gui layout/library
 
The CIDT model:
- Concern (ie gui, data),
- Interface for each concern, the Python methods defining the model's interface (not necessarily the data model).
- Dispatcher for each concern managed by OS which manages system resouces like a graphics image or network stream or file IO of data,
- Translator between communicating concerns. The translator would usally be reduced down into an object with generic methods like .read(), write(), open(), close(), start(), stop(), init(), mode(), isWhatEverStatus()-like.
 
The problem with this pattern is the data stream controller and the gui loop are OS controlled; meaning how window events are stored and sent to event handlers and how stdio devices are resources controlled by the OS became too much for my brain at the time and working out how to break my code down just started getting to complicated. So I went back to just doing it the straight and narrow way (ie the wx.Frame that does it all).
 
The other problem I have as an inexperienced OOP and Python programmer is what form the reactor/loops take; meaning do I make one reactor a process and one a thread, use 2 seperate processes and IPC or the broader RPC or go lower level and use just sockets, or whatever you get the idea. I know that wxPython needs to be the primary process. But if I wanted to replace that GUI package, would the next GUI package need to take a different place in the looping parent/child structure. Again.. too much thinking, (ie back to the wx.Frame that does it all).
 
I needed none of these questions answered if I didn't mind programming in however the situation called for for each script/app whatever. But if I wanted to develope apps with reusable interfaces, and standarize my tools it seemed prudent to at least look into all this.
 
I can also ponder these thoughts because at this time I program Python on as purely reacreation exercise. Maybe these words will actually produce some useful insight.
 

Peter Damoc

unread,
Sep 25, 2011, 11:34:53 AM9/25/11
to wxpytho...@googlegroups.com
Are you referring to this page:
http://wiki.wxpython.org/ModelViewPresenter/
If this is the case, I must apologize. The lack of clarity might have
been my fault. :)


On Sun, Sep 25, 2011 at 8:33 AM, Dev Player <devp...@gmail.com> wrote:
> I thought I saw the MVP OOP pattern demo'd for wxPython to seperate object
> "interface" (ie event handlers). Although it's called MVP it was more like
> MVIP (an ancronmy I made up to show the way I saw the model demo'd) and the
> demo clumped the interface in with either the view or the presentation part
> of the pattern.


--
There is NO FATE, we are the creators.
blog: http://damoc.ro/

Dev Player

unread,
Sep 25, 2011, 12:12:08 PM9/25/11
to wxpytho...@googlegroups.com
Yes that's it.
 
BTW I love the stucture of MVP. Although I did struggle with it. Inparticular, I could not figure out how to make it grow to multiple top level frames, multiple windows, threaded and subprocessed. And that was when I started with Python, and wxPython.
 
What I wanted to try to do with the MVP was to remake the wxPython Demo with it. But I wasn't and perhaps still not savy enough to do it. I wanted to change the wxPython demo main frame to the aui (as agw wasn't intro'd yet) widget and put all the wxPython widget demos into it as pluggle system. I thought that'd be a good framework or template to make further apps and thought it'd be easier reworking the demo then starting from scratch. Live and learn.
 
 

Kevin Ollivier

unread,
Sep 25, 2011, 12:54:19 PM9/25/11
to wxpytho...@googlegroups.com
Hi,

On Sep 24, 2011, at 10:33 PM, Dev Player wrote:

[snip]
 
The other problem I have as an inexperienced OOP and Python programmer is what form the reactor/loops take; meaning do I make one reactor a process and one a thread, use 2 seperate processes and IPC or the broader RPC or go lower level and use just sockets, or whatever you get the idea. I know that wxPython needs to be the primary process. But if I wanted to replace that GUI package, would the next GUI package need to take a different place in the looping parent/child structure. Again.. too much thinking, (ie back to the wx.Frame that does it all).

Yeah, the problem is mostly over-thinking the level of abstraction. :) It will just give you a headache. Programmers are taught to think in abstractions, but there's a point where abstractions lose any practical benefit and actually cause you to come up with overly complex designs to solve simple problems. Even MVC vs. MVP seems to me to be based on a misunderstanding of what MVC is. MVP, from what I've read of it, reads like someone learning MVC by reading articles, misunderstanding it, and creating MVP to 'fix' what they saw was wrong with MVC, which IMHO is just re-creating MVC and calling it by another name. :) I will use the term MVC, but if you want to consider what I'm saying MVP that's fine.

Here's an easy to understand way of writing more MVC-compliant apps with wxPython. Take your wx.Frame subclass with everything in it, convert it to an wx.EvtHandler subclass that takes a wx.Frame as an argument (along with any data objects you need). Then replace any calls to wx.Frame API from self.Whatever to self.frame.Whatever. Then, when your app starts, initialize your frame, your data objects, and then initialize your EvtHandler subclass and pass them in, like so:

class MyController(wx.EvtHandler):
def __init__(self, frame, data):
self.frame = frame
self.data = data

# create child controls
self.button = wx.Button(self.frame, -1, "Load")
... 

# bind events
self.button.Bind(wx.EVT_BUTTON, self.OnLoadClicked)

def OnLoadClicked(self, event):
self.LoadData()

def LoadData(self):
self.data.load_data()
# populate wx.Frame controls with data

class MyApp(wx.App):
def OnInit(self):
frame = wx.Frame(None, -1, "MVC Frame")
data = MyDataStructure()
self.controller = MyController(frame, data)

# eventually...
# self.controller1 = DataViewController(frame, data)
# self.controller2 = AnimationController(frame)
# etc.

frame.Show()
return True

Now all your code is no longer in a wx.Frame subclass. :) And you'll note, a small app written this way will have only a few more lines of code than a traditional, all in wx.Frame app does. People way overestimate what is required or expected of MVC abstraction. They think that if you use MVC you must break everything into tiny, tiny bits. You don't need to. A small MVC app will look much like a traditional wx app does, as you can see above. However, as the app grows, this model makes refactoring and reuse simpler. When you add new code, instead of having only one choice, that is, to just stuff it in the wx.Frame subclass, you can choose - if you feel the code's reusable, you can make a new, shareable controller for it. If not, you can just put it your primary controller, just the same as you'd do if your wx.Frame was the event handler. You may always do it that way. But the key is that you have that choice.

It's really that simple. Move your code from a wx.Frame subclass into a wx.EvtHandler subclass and you're doing all that's required. You may never make more than one Controller for your app. It's okay. You aren't angering the MVC gods by doing so. ;-) The point of adopting MVC is that it facilitates creating discrete controllers for discrete behaviors when that is the best approach, though small apps may never need to.

Anyway, I do appreciate that until the toolkit itself considers adopting some of these ideas for its code, it's hard to get a solid grasp of the concept, and it feels like you're fighting the toolkit to use it. Even as I promote MVC, I myself find it hard to give up on the traditional way of writing wxPython code since I'm working with a lot of legacy code or code written by others. When you see and work with that code all the time, the path of least resistance is to simply stick with that model for everything. However, since I code with other toolkits, I also know the pitfalls of the wx approach, and I don't think it's good to rest on one's laurels and stop looking for better ways of doing things. I should probably at least clean up my InlineTextSearchController and contribute it, so that people who need inline text search can use it and get an idea of how controllers work.

Regards,

Kevin

I needed none of these questions answered if I didn't mind programming in however the situation called for for each script/app whatever. But if I wanted to develope apps with reusable interfaces, and standarize my tools it seemed prudent to at least look into all this.
 
I can also ponder these thoughts because at this time I program Python on as purely reacreation exercise. Maybe these words will actually produce some useful insight.
 

Dev Player

unread,
Sep 25, 2011, 11:17:14 PM9/25/11
to wxpytho...@googlegroups.com
Good points.
 
The comments in the wxApp class helped me understand multiple windows and controllers in the app better. That was a stumbling block for me.
 
Just as an odd note; you've created an app object, an event handler called the controller, a data namespace, and a frame object.
 
I could be wrong on this but...
 
This reminds me of my old Windows C SDK (not C++) programming days and how the frame is really an EventHandler object with a GDC (graphics device context) attribute used to display graphics. The frame has some init code and paint code to draw borders and title bar. This was likely done to keep code in that all important 64K memory block back in the day (where not it's not revelent with todays OSes).
 
When you create the frame you're just not using it's event handler and you're laying on another eventhandler without that DC attribute for the OS to manage. To twist it around, you are creating two event handlers, one with a GDC and one without. and then you use the eventhandler without the GDC to handle graphic events for the event handler with the GDC. But I'm not sure of this anymore as it was some 12+ years ago for me.
 
This is probably not revelent on todays computers. But do consider this; if your window has lots of controls, meaning windows, meaning eventhanders with graphic device contexts, and you make a bunch of seperate event handers to manage the GDIs (for border and titlebar and the like) you could end up with some slow control updates.
 
btw my memory is based on MS Windows platforms. Unix and like I've no programmer experience with.
 
How windows 7 and new OSes manage the native eventhandler objects and the GDIs could be very different today then what I thought the way it was.
 

Peter Damoc

unread,
Sep 26, 2011, 4:17:42 AM9/26/11
to wxpytho...@googlegroups.com
Creating great code requires a lot of discipline and a lot of restrain.
The Dark Side is quicker, more seductive and it gives you the illusion
of progress only to lure you into hell.

Ideally, we should all STOP and think just as frequently as we type.
Blend strategy and tactics together.

I don't do that and my code ends up being crappy most of the time.
I sin and I'm punished by my sins.

Anyway, if my intuition is correct, even if you failed in your attempt
with the redesign of the Demo, you've learned a lot about code
structure.

--

Peter Damoc

unread,
Sep 26, 2011, 4:29:01 AM9/26/11
to wxpytho...@googlegroups.com
MVP might seam like a regurgitation of MVC by someone who fails to
understand it but, IMHO it is not this.

If I would have to describe the difference between MVC and MVP, I
would point to the effort to make the View code as dumb as possible.

The Controller code is broken in two: Interactor and Presenter where
the Interactor provides insulation of the Presenter from the View.

If done right, the Interactor and the View are dumb, dumb, dumb and
are the only zones where something like wxPython appears.
Being so dumb minimizes failure in these components. It also means
that another toolkit could be used (theoretically).

The PassiveView pattern presented by Martin Fowler as an evolution of
MVP follows closely to this "dumbification" of the View.

On Sun, Sep 25, 2011 at 7:54 PM, Kevin Ollivier
<kevin...@theolliviers.com> wrote:
...


> Yeah, the problem is mostly over-thinking the level of abstraction. :) It
> will just give you a headache. Programmers are taught to think in
> abstractions, but there's a point where abstractions lose any practical
> benefit and actually cause you to come up with overly complex designs to
> solve simple problems. Even MVC vs. MVP seems to me to be based on a
> misunderstanding of what MVC is. MVP, from what I've read of it, reads like
> someone learning MVC by reading articles, misunderstanding it, and creating
> MVP to 'fix' what they saw was wrong with MVC, which IMHO is just
> re-creating MVC and calling it by another name. :) I will use the term MVC,
> but if you want to consider what I'm saying MVP that's fine.

--

jmfauth

unread,
Sep 27, 2011, 7:49:38 AM9/27/11
to wxPython-users


On 26 sep, 10:17, Peter Damoc <pda...@gmail.com> wrote:
> Creating great code requires a lot of discipline and a lot of restrain.
> The Dark Side is quicker, more seductive and it gives you the illusion
> of progress only to lure you into hell.
>
> Ideally, we should all STOP and think just as frequently as we type.
> Blend strategy and tactics together.
>
> I don't do that and my code ends up being crappy most of the time.
> I sin and I'm punished by my sins.
>

---

I little story.

I do love to toy with a Python interactive interpreter. So,
I wrote mine: Py2 and wxPy < 2.9 ansi builds and as much as
possible, a clear GUI/pure Python separation.
Usage of the STC.

I also have a wx-unicode-build version. I'm not satisfied
with it.

When Python 3.0 came out. I had no choice. It was time to
take a serious look at tkinter. I wrote a new interactive
interpreter based on the skeleton of my previous one.
To my surprised, I was done in one and half day! Not as
polished as the wxPy version, but fully working.
Usage of the ScrolledText.

Ok, I had learned tkinter. Time to port it to Python2
and Tkinter. After 20 minutes, I realized, it was so
easy and it finally does not bring something interesting,
I abandonned it.

So, it was not so complicate. Let's try with PyQt4 for
Py2. Done, in practically one long day.
Usage of the QScintilla.

Then arrived PySide, Py2. Compared to PyQt it has no QScintilla
widget. So, I took a look at the QPlainTextEdit (btw. extremely
powerful). Done, in let say, 2 days. Very importantly, in this
version, I decided to work in a plain full unicode mode.
In fact, PySide does not simply allow to write correct/running
code in a non unicode mode. Excellent!
Usage of the QPlainTextEdit.

Next and logical step: the PySide version ported to PyQt4 for
Python 3. Believe or not, done in 20 minutes.

The lessons
- The more one uses pure Python code, the better it is.
- The main job was not to write the interactive intepreter,
but a solid base text control containing all the APIs,
supposed to be used in an interactive interpreter.
- I do not spend most of the time in coding. I spend my
time in the documentation and in learning the text widgets
documentation, eg. how to style a piece of text. It was
especially true for the QPlainTextEdit widget.


As I love to toy with the coding of the characters. I also
have some really tricky versions allowing to modify the
sys.stdout.encoding on the fly!

Most probably, a wxPy29 version will never exist.

jmf

Tobias Weber

unread,
Sep 27, 2011, 10:01:19 AM9/27/11
to wxpytho...@googlegroups.com
I am playing around w/ wx.lib.mixins.listctrl. (ListCtrlEdit in the demo)
Everything fine so far- I was wondering if there is a way to make only
one cell in my list editable, for example have a list and have the user
type in the 1st field a umber, whereas the rest is not editable...

Cheers

Cody

unread,
Sep 27, 2011, 10:07:14 AM9/27/11
to wxpytho...@googlegroups.com
Hi,

Override its OpenEditor method and only call the super classes method
for the cell(s) you want to let the editor open for.


Cody

jmfauth

unread,
Sep 27, 2011, 11:09:24 AM9/27/11
to wxPython-users


On 27 sep, 16:01, Tobias Weber <tobias.we...@roglink.net> wrote:
....



Mister the Geshaeftsfuehrer (German, plain ascii and not
mac-roman).

Would you be so kind to open a new thread and not, practically
and systematically, modifiy the subject of a current thread?
Thank you.

I'm so stupid on this "mailing stuff", I do not even know
how to do it.

jmf

Tobias Weber

unread,
Sep 27, 2011, 11:14:14 AM9/27/11
to wxpytho...@googlegroups.com
oops - will do.
Safe some of your sarcasm though - u sure do not wanna run out of it ;-)

Am 27.09.11 17:09, schrieb jmfauth:

jmfauth

unread,
Sep 27, 2011, 11:26:43 AM9/27/11
to wxPython-users


On 27 sep, 17:14, Tobias Weber <tobias.we...@roglink.net> wrote:
> oops - will do.
> Safe some of your sarcasm though - u sure do not wanna run out of it ;-)
>

Don't take it too seriously.

Out of curiosity, are you really an OSX user? I came to this, when
I saw your mail signature prior the "Google change" a few days ago.

jmf

Kevin Ollivier

unread,
Sep 27, 2011, 11:52:31 AM9/27/11
to wxpytho...@googlegroups.com
Hi Peter,

On Sep 26, 2011, at 1:29 AM, Peter Damoc wrote:

> MVP might seam like a regurgitation of MVC by someone who fails to
> understand it but, IMHO it is not this.
>
> If I would have to describe the difference between MVC and MVP, I
> would point to the effort to make the View code as dumb as possible.
>
> The Controller code is broken in two: Interactor and Presenter where
> the Interactor provides insulation of the Presenter from the View.
>
> If done right, the Interactor and the View are dumb, dumb, dumb and
> are the only zones where something like wxPython appears.
> Being so dumb minimizes failure in these components. It also means
> that another toolkit could be used (theoretically).

Well, this is in my reading a variation on MVP (MVIP?), not MVP as originally constructed, but yeah, it's just adding one more layer of abstraction. Certainly useful for more complex scenarios.

How I see this sort of thing is that once you start thinking in terms of MVC, these sorts of evolutions happen naturally. Once you get into the habit of breaking things into discrete pieces, you may find that a particular app you're working on requires a 4th or 5th component, say, to allow web + native GUI instead of just native GUI alone. The key, I think, is to start people on that path so that they move away from designs that encourage speghetti code.

Regards,

Kevin

> The PassiveView pattern presented by Martin Fowler as an evolution of
> MVP follows closely to this "dumbification" of the View.
>
> On Sun, Sep 25, 2011 at 7:54 PM, Kevin Ollivier
> <kevin...@theolliviers.com> wrote:
> ...
>> Yeah, the problem is mostly over-thinking the level of abstraction. :) It
>> will just give you a headache. Programmers are taught to think in
>> abstractions, but there's a point where abstractions lose any practical
>> benefit and actually cause you to come up with overly complex designs to
>> solve simple problems. Even MVC vs. MVP seems to me to be based on a
>> misunderstanding of what MVC is. MVP, from what I've read of it, reads like
>> someone learning MVC by reading articles, misunderstanding it, and creating
>> MVP to 'fix' what they saw was wrong with MVC, which IMHO is just
>> re-creating MVC and calling it by another name. :) I will use the term MVC,
>> but if you want to consider what I'm saying MVP that's fine.
>
> --
> There is NO FATE, we are the creators.
> blog: http://damoc.ro/
>

Tim Roberts

unread,
Sep 27, 2011, 2:20:28 PM9/27/11
to wxpytho...@googlegroups.com
Tobias Weber wrote:
> oops - will do.
> Safe some of your sarcasm though - u sure do not wanna run out of it ;-)

I like that line -- I will remember it.

As someone who uses way more sarcasm than is necessary, I have to say
there is no evidence that I will ever run out. It seems to be the very
essence of a "renewable resource". Every time I try to slack off,
someone comes along and causes me to generate a lot more.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Tobias Weber

unread,
Sep 27, 2011, 4:33:25 PM9/27/11
to wxpytho...@googlegroups.com
"cynism is my armour, sarcasm my sword and irony my shield ...."

I sure can take it and hope that all of you never run out of it ;-)

Cheers

Am 27.09.11 20:20, schrieb Tim Roberts:


> Tobias Weber wrote:
>> oops - will do.
>> Safe some of your sarcasm though - u sure do not wanna run out of it ;-)
> I like that line -- I will remember it.
>
> As someone who uses way more sarcasm than is necessary, I have to say
> there is no evidence that I will ever run out. It seems to be the very
> essence of a "renewable resource". Every time I try to slack off,
> someone comes along and causes me to generate a lot more.
>


--
--------------------------------------------------
Tobias Weber
CEO

The ROG Corporation GmbH
Donaustaufer Str. 200
93059 Regensburg
Tel: +49 941 4610 57 55
Fax: +49 941 4610 57 56

www.roglink.com

Gesch�ftsf�hrer: Tobias Weber
Registergericht: Amtsgericht Regensburg - HRB 8954
UStID DE225905250 - Steuer-Nr.184/59359
--------------------------------------------------

Peter Damoc

unread,
Sep 28, 2011, 3:29:23 AM9/28/11
to wxpytho...@googlegroups.com
Hi Kevin,

On Tue, Sep 27, 2011 at 6:52 PM, Kevin Ollivier
<kevin...@theolliviers.com> wrote:
...


> How I see this sort of thing is that once you start thinking in terms of MVC, these sorts of evolutions happen naturally. Once you get into the habit of breaking things into discrete pieces, you may find that a particular app you're working on requires a 4th or 5th component, say, to allow web + native GUI instead of just native GUI alone. The key, I think, is to start people on that path so that they move away from designs that encourage speghetti code.

What you said here cannot be overemphasized. Any kind of design is
better than no design at all.
My code naturally evolves towards spaghetti and if I don't intervene
I'm left with unmaintainable code.

It's a struggle.
Peter

Damon

unread,
Sep 28, 2011, 9:37:52 AM9/28/11
to wxPython-users

On Sep 28, 3:29 am, Peter Damoc <pda...@gmail.com> wrote:
> requires a 4th or 5th component, say, to allow web + native GUI instead of just native GUI alone.

I've found it difficult to create even a smallish app that can run
either/both wxPython GUI or command line. I need to spend more time
looking at MVC tutorials and discussion.

/D


C M

unread,
Sep 28, 2011, 12:45:27 PM9/28/11
to wxpytho...@googlegroups.com

I've found it difficult to create even a smallish app that can run
either/both wxPython GUI or command line.  I need to spend more time
looking at MVC tutorials and discussion.

I hear you.  I tried taking a 5,000 LOC app made without any design principles and "MVC'ing it" and it was too painful to continue and I resigned myself to a kind of (I guess)  ravioli code in which each GUI section is self-contained--GUI + data--and so is modular in that way at least (and even then I occasionally use PubSub if doing otherwise would strongly violate the Law of Demeter).  It won't be portable to, say, a web app at all, but I don't really care, so for now I am enjoying the ravioli.  Starting an MVC design *from scratch*, though, has got to be easier than retrofitting code to be MVC.

Che

Chris.Barker

unread,
Sep 28, 2011, 2:01:02 PM9/28/11
to wxpytho...@googlegroups.com

> I've found it difficult to create even a smallish app that can run
> either/both wxPython GUI or command line. I need to spend more time
> looking at MVC tutorials and discussion.

I have a development philosophy that can't be original, but have never
seen anyone give it a name:

When you set out to build an application:

First:
Write the libraries that you wish already existed to build you app

Then:
Put those libraries (and other pre-existing ones) together to build
your app.


By thinking in terms of libraries, it really helps me clarify where
given code should go -- is this specific to this particular app, or is
this a general-purpose method that anyone doing something similar would
want?

In the above case, the command line app and GUI app are two different
apps, but they would use (mostly) the same libraries--build those
libraries, and the apps will be pretty easy.

In fact, when you start out knowing you have two UIs to write, it should
be pretty easy -- if it'll only be used by the GUI, put it with the GUI
code, if it will only be used by the CLI, put it there, if it will be
used by both, put it in one of your libraries.

NOTE: libraries can be GUI libs too, if there is general purpose GUI
functionality in there.

NOTE 2: you can (should) write test code for your libraries that have
nothing to do with the UI as well -- so in that sense you always have to
interfaces to support -- your app UI, and your tests.

-HTH,
-Chris


--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris....@noaa.gov

Gadget/Steve

unread,
Sep 28, 2011, 2:29:10 PM9/28/11
to wxpytho...@googlegroups.com
My current code base at work:
ExecuteScripts
|- Utility Scripts
|- MessageStructures
|- Comms
etc

Adding a new application that is aware of all the data, comms, etc, is
very fast. The suite is also pyexe converted to 15+ exes some dos some
windows...

Gadget/Steve

Robin Dunn

unread,
Sep 28, 2011, 6:10:14 PM9/28/11
to wxpytho...@googlegroups.com
On 9/28/11 11:01 AM, Chris.Barker wrote:
>
>> I've found it difficult to create even a smallish app that can run
>> either/both wxPython GUI or command line. I need to spend more time
>> looking at MVC tutorials and discussion.
>
> I have a development philosophy that can't be original, but have never
> seen anyone give it a name:
>
> When you set out to build an application:
>
> First:
> Write the libraries that you wish already existed to build you app
>
> Then:
> Put those libraries (and other pre-existing ones) together to build your
> app.
>

Agreed. I find myself doing this or something like it in most projects.

werner

unread,
Sep 29, 2011, 8:36:26 AM9/29/11
to wxPytho...@googlegroups.com
On 09/25/2011 06:54 PM, Kevin Ollivier wrote:
...
This is a bit long, hope others don't mind and hopefully this might be useful for other MVC noobs.

I recently started to rewrite my app to apply what I have learned over the last few years (mainly on this list , by reading the "books" and by lots of trial and error) and hopefully come up with something better, easier to maintain and to extend.

While I followed the different MVC/MVP discussions over the years on this list I never got a feeling that I grasp it enough and have started the re-write without applying either of these patterns, but I have second thoughts after seeing Kevin's post above which at first sight makes MVC simpler/easier to understand.

But - applying it to my own stuff is another story.

I use a database and I use SQLAlchemy's declarative, so all the SQL to Python mapping is done by SA and I put all that into a package "model" which I like to keep compatible to what e.g. Turbogears would expect in it.

The app will be a Wine book and a Recipe book, so these are my two main controllers?  Then there are a bunch of dialogs to maintain master data etc such as country, region, wine type etc etc, so each of those would be a controller?

For my re-write I decided to start doing part of the sa model, and widget stuff and test them with the master data maintenance dialogs.

In an app like this where is the main code of e.g. "CreateItemClicked" method going?

I was trying to explain it in words where I think things should go, but some pseudo code is probably better.

controllers.base - contains all the common code to setup controls etc which is currently in my dialog_base model which I would need to change to be a wx.EvtHandler based class.

controllers.country - inherits from base
def __init__(self, view, model):
    self.CreateControls(view, dictWithInfoForControls)
    self.view = view
    self.model = model

def CreateItemClicked(self, evt):
   self.model.CreateItem(self._isLocalized)
   self.LoadData()
   self.EnableControls()

def LoadData(self):
   self.InitDialog()  # I use validator.TransferToWindow to load indiv. controls data

def SaveData(self):
   self.TransferDataFromWindow()
   self.model.SaveData()
   self.InitDialog()

def EnableControls()
    self.DoEnableControls(self.stdCtrls, True)
    if self._isLocalized:
        self.DoEnableControls(self.locCtrls, True)
        self.locCtrls[0].SetFocus()
    else:
        self.stdCtrls[0].SetFocus()

    # buttons
    self.save.Enable()
    self.saveAndClose.Enable()
    self.undo.Enable()
    self.create.Enable()

model.country
def CreateItem(isloc):
   self.dbItem = modelsa.country
   modelsa.session.add(self.dbItem)
   if isloc:
        self.dbItemLoc = modelsa.country_localized
        self.dbItemLoc.language = wx.GetApp().userlanguage
        modelsa.session.add(self.dbItemLoc)

view.country
- a sized_controls.SizedDialog
def __init__(self, title='MVC maintain country information):
self.data = model.country()
self.controller = controller.country(self, self.data)


In other words, how do I check/make sure that things are in the right place (model, view, controller)?

Werner

Kevin Ollivier

unread,
Sep 29, 2011, 12:19:48 PM9/29/11
to wxpytho...@googlegroups.com
For now, I would suggest simply thinking in the same way you did when subclassing wx.Frame - that is, whatever code you would put in your wx.Frame subclass would go into the Controller instead. The breakdown of controllers is not a science, and there aren't singular 'right' answers. 

For my re-write I decided to start doing part of the sa model, and widget stuff and test them with the master data maintenance dialogs.

In an app like this where is the main code of e.g. "CreateItemClicked" method going?

Controller.  
When you're writing model or view code, think as if you're writing them for a GUI toolkit or a data toolkit, not for your app. Ask yourself, "could I submit this dialog, view, etc. to the wxPython project?" So in the code above, for example, notice that if you wanted to use view.country in some other app you were working on, that new app would also be required to include model.country() and controller.country(). The Controller solves this reusability problem by being the place where all 'non-reusable' code goes. The Controller can store references to other parts of your app, like the model and the view, but the models and views themselves should be written to be reusable and hence not rely on other parts of your app. 

The fix for your code above would be pretty simple. Instead of initializing your model and controller inside of your view, just do it outside of the view, like so:

# doesn't have to be here, this is just for example purposes
def OnInit(self): 
# if you wanted, you could actually initialize both the view and model inside controller.country's __init__ method, too.
dialog = view.country(self, -1)
data = model.country()
self.countryController = controller.country(dialog, data)

Does this help?

Regards,

Kevin

Werner

werner

unread,
Sep 30, 2011, 9:44:06 AM9/30/11
to wxpytho...@googlegroups.com
On 09/29/2011 06:19 PM, Kevin Ollivier wrote:
...
# doesn't have to be here, this is just for example purposes
def OnInit(self): 
# if you wanted, you could actually initialize both the view and model inside controller.country's __init__ method, too.
dialog = view.country(self, -1)
data = model.country()
self.countryController = controller.country(dialog, data)

Does this help?

I think so, will just have to give it a try and see.

Thanks
Werner

werner

unread,
Oct 1, 2011, 6:06:53 AM10/1/11
to wxpytho...@googlegroups.com
I think I got it.

The thing which is feeling strange is the view as it is really just one line initializing some container widget.

My MasterDataController was previously a dialog which the country dialog (and all other master data dialogs) inherited, as it now is wx.EvtHandler based it allows me to re-factor that so it is not only usable for my master data dialogs/controllers but also for other things.

Kevin, thanks for opening my eyes.

Werner

Kevin Ollivier

unread,
Oct 4, 2011, 12:24:41 PM10/4/11
to wxpytho...@googlegroups.com
Hi Werner,

On Oct 1, 2011, at 3:06 AM, werner wrote:

On 09/30/2011 03:44 PM, werner wrote:
On 09/29/2011 06:19 PM, Kevin Ollivier wrote:
...
# doesn't have to be here, this is just for example purposes
def OnInit(self): 
# if you wanted, you could actually initialize both the view and model inside controller.country's __init__ method, too.
dialog = view.country(self, -1)
data = model.country()
self.countryController = controller.country(dialog, data)

Does this help?

I think so, will just have to give it a try and see.
I think I got it.

The thing which is feeling strange is the view as it is really just one line initializing some container widget.

You can put the controls inside the frame / dialog itself if you want. The thing is that when doing it, you want to be sure to make an API for getting / setting any control data or properties within it, as you'll be doing that from the Controller. i.e. again, you'd be designing your dialog or frame to be self-contained, as if it could be used by other apps with different data sources and controllers. So, for example:

class country(wx.Dialog):
def __init__(self, *a, **kw):
wx.Dialog.__init__(self, *a, **kw)

self.CountryNameChoice = wx.Choice(self, -1, choices=[...])
self.WorldMap = MyWorldMapControl(self, -1, ...)

# other initialization ,,,

def GetSelectedCountry(self):
return self.CountryNameChoice.GetStringSelection()

def SetSelectedCountry(self, name):
self.CountryNameChoice.SetStringSelection(name)

def SetWorldMapBackgroundColor(self, color):
# code to do so here ...

class controller(wx.EvtHandler):
def __init__(self, model, view):
country = model.getCountry()
view.SetSelectedCountry(country)

I suggested creating the child controls in the Controller because that's the most straightforward way to transition from the 'traditional' wx coding style. Once you get more familiar with how Controllers work, doing things like the above to separate out the view code becomes more natural.

My MasterDataController was previously a dialog which the country dialog (and all other master data dialogs) inherited, as it now is wx.EvtHandler based it allows me to re-factor that so it is not only usable for my master data dialogs/controllers but also for other things.

Kevin, thanks for opening my eyes.

I'm glad it's helpful to you. :)
Reply all
Reply to author
Forward
0 new messages