patternpythonMinor
Pubsub-driven MVC application with wxPython
Viewed 0 times
mvcapplicationwithwxpythonpubsubdriven
Problem
I'm still learning Python, so I tried to build a basic MVC app using wxPython and pubsub. While it seems to work fine, the code seems to be getting out of hand.
In model I decided against using traditional (e.g. Java) accessors and went with the more Pythonic approach of properties. I only wanted to set the setters, but ended up needing to set the getters too (because the variable name had to change to prevent recursion). What's the preferred way to do this?
Next, the flow for setting each variable seems a mess. Right now, changing the name in view publishes a message which controller is subscribed to, so it sets the name in model, which publisher another message which controller is subscribed to, which sends a message to view, which finally does something with the values (the last part is not really required at the moment, but should be in many cases). Is this all peachy, or am I missing something?
As for any other blunders, I'd be happy to hear them!
I mostly followed Mike Rooney's Code Sample.
```
"""
A simple attempt at a pubsub-driven MVC application with wxPython
"""
import wx
import wx.lib.pubsub
# this seems to be required -- bug?
pub = wx.lib.pubsub.Publisher()
class Model(object):
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
pub.sendMessage("name.changed", self.name)
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self._age = value
pub.sendMessage("age.changed", self.age)
class View(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, title="MVC test", size=(200, 150))
# setup sizers
self.padding_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.sizer = wx.FlexGridSizer(2, 2, 8, 25)
self.sizer.AddGrowableCol(1, 1) # make the second column fit availab
In model I decided against using traditional (e.g. Java) accessors and went with the more Pythonic approach of properties. I only wanted to set the setters, but ended up needing to set the getters too (because the variable name had to change to prevent recursion). What's the preferred way to do this?
Next, the flow for setting each variable seems a mess. Right now, changing the name in view publishes a message which controller is subscribed to, so it sets the name in model, which publisher another message which controller is subscribed to, which sends a message to view, which finally does something with the values (the last part is not really required at the moment, but should be in many cases). Is this all peachy, or am I missing something?
As for any other blunders, I'd be happy to hear them!
I mostly followed Mike Rooney's Code Sample.
```
"""
A simple attempt at a pubsub-driven MVC application with wxPython
"""
import wx
import wx.lib.pubsub
# this seems to be required -- bug?
pub = wx.lib.pubsub.Publisher()
class Model(object):
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
pub.sendMessage("name.changed", self.name)
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self._age = value
pub.sendMessage("age.changed", self.age)
class View(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, title="MVC test", size=(200, 150))
# setup sizers
self.padding_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.sizer = wx.FlexGridSizer(2, 2, 8, 25)
self.sizer.AddGrowableCol(1, 1) # make the second column fit availab
Solution
It mostly looks pretty good. I have just a couple tweaks to suggest.
You have
The example from the wxpython wiki does
I think using that form of the import will let you drop the line where you instantiate the Publisher.
I like to put my mainline code in a main() routine right after the imports so it's clear where the work begins
Then at the bottom of the file,
You have
import wx.lib.pubsub
# this seems to be required -- bug?
pub = wx.lib.pubsub.Publisher()The example from the wxpython wiki does
from wx.lib.pubsub import Publisher as pubI think using that form of the import will let you drop the line where you instantiate the Publisher.
I like to put my mainline code in a main() routine right after the imports so it's clear where the work begins
def main(args):
#create the wx app
app = wx.App(False)
# pass the app to the controller
controller = Controller(app)
# start the app running
app.MainLoop()Then at the bottom of the file,
if __name__ == '__main__':
# call main rather than hiding the payload down here
main(sys.argv)Code Snippets
import wx.lib.pubsub
# this seems to be required -- bug?
pub = wx.lib.pubsub.Publisher()from wx.lib.pubsub import Publisher as pubdef main(args):
#create the wx app
app = wx.App(False)
# pass the app to the controller
controller = Controller(app)
# start the app running
app.MainLoop()if __name__ == '__main__':
# call main rather than hiding the payload down here
main(sys.argv)Context
StackExchange Code Review Q#17939, answer score: 4
Revisions (0)
No revisions yet.