Wednesday, February 5, 2014

Example For wxPython pureMVC Using Eclipse IDE with PyDev Plugin : Tryout

Blah Blah....

I was planning to get my hands dirty with python :) but the problem is i hate to do it with simple stuff. But one has to go through a simple Hello World example :( . So after playing some with Python Command Line Interpreter, it was time to do some work that means something .
I have been programming in ActionScript and Flash from 8 to 10 years now, and I learnt to do it in pretty object oriented  fashion , and using some frameworks. I started with +The PureMVC Framework  for ActionScript 3.0 during my internship at White Rabbit Studios. It was first time I knew about some framework. But pureMVC was hard to follow , not its abstraction , but its boilerplate nature. I was and still am , a hobby programmer and to make a small working application , pureMVC needs many many classes to write/extend. Later I tried Robotlegs 1.5 for ActionScript3.0 and i am in love with it since.
Now as i "wish" to learn +Python , (also i "wish" to learn +Haxe ;) ) , I need some framework to write some "large" application , with MVC pattern. So PureMVC was the only good choice i can find . I hope some cool guy would write a Robotlegs port for Python.



Last night i spend some good time playing with PureMVC for Python , starting with refreshing my memory from an old ActionScript Example.
I was using WxPython for the first time too , and most of the time i spend understanding and trying WxPython ( as i could not find some good API for it , had to go through demo code provided by WxPython).

Lets Get Started

So here is my plan , i want to make A simple Hello World in Python , on top of PureMVC , and WxPython. Some window (view) that contain a Button,input text and output text fields. When I click or Interact on my Button , the entered text should go to backend (pureMVC minus V) code and get stored to some Value object and then the change in data model is notified and the the Window is updated.
Its a simple MVC paradigm , with some accessory actors provided by PureMVC framework , you can read more about it at puremvc.org . Check its Conceptual diagram .I am just trying to tell the steps to up and running a basic Python app with PureMVC.

Eclipse And PyDev

I'm using Python 2.7 , downloaded it , install it. Then installed Eclipse 64-bit for widows, and installed plugin PyDev. Also downloaded and install WxPython binaries for windows.
After all the installation , PyDev needed to be configured , Eclipse is ready for Python development.
Now PureMVC , i download the framework from its gitub , and extracted it Src directory to \Python27\Lib
ie " \Python27\Lib\puremvc". I don't why pureMvc's Setup.py was not working for me.
Now i have all the libraries placed and set . Now Creating PyDev project .

Project

Create a new PyDev project , if everything was configure right you will see a linked python settings in the project , like shown in the picture . Right click the project and Add New Source Folder ; i name mine src .
Add new PyDev Module to the Src folder , select Main Module.
Eclipse PyDev Python Project

Now all is set , its time to wire-up PureMVC . This Main.py will only be firing up our puremvc application.
PureMvc requires an Application facade in singleton setting.Now I will be creating files for the example application.


  • ApplicationFacade.py
  • controller.py
  • views.py
  • mediators.py
  • model.py
  • vo.py

The source folder for the project is given at the end of the post. Here I try to explain whats going on.

ApplicationFacade.py

This py file contains only one Class ApplicationFacade (which is same as file name and you will see the use of ApplicationFacade.ApplicationFacade to refer the class),extending puremvc.patterns.facade.Facade.
It has two events STARTUP and DATA_CHANGED.
It exposes one static method getInstance()  to get only one instance of Applicationfacade.
Two override methods initializeFacade and initialiazeController.
In later method we register only one Command to an Event/notification , StartupCommand.
When we launch our application in Main.py , we call ApplicationFacade.getInstance().startup(view)  and give the refernce to our Wx.Frame object or class as viewcomponent.
The startup method startup the puremvc by sending START_UP notification and the registered command is executed.

Controller.py

It contains only one command class StartupCommand,which ovveride execute method of its parent class SimpleCommand from puremvc world.
Here we register  data model and view of our application.

self.facade.registerProxy(model.UserProxy())
self.facade.registerMediator(mediators.MainFrameMediator(mainWindow))


Now, we will be writing UserProxy class in mode.py and MainFrameMediator in mediators.py
here mainWindow is the reference of the main frame which we will be passing to ApplicationFacade.startup() call.
First look at Views+Mediator

Views.py

In pureMVC , a view is 2-tier object , means the Visual controlls called Component and its Mediator.
I am using term Views for component here and a mediator attached to it (like in Robotlegs).
WxPython only exists in our views. In our example , I am using only one simple view.
Views.py contains two classes , MainView and MainFrame. The MainView is extending wx.App class and it is the requirement of WxPython framework.
The MainView creates our MainFrame object which is wx.Frame and it contains other controlls like button,text field etc.
Here the concept is , A wx.TextCtrl is used to receive user input, a wx.Button is clicked and An Event is fired which carries the entered text along with it.
The wx.StaticText is used to display the entered text.
The tricky part here was binding events , which i have no idea about , for wxPython framework, so i just follow the demo from wxPython and pureMVC example.

Mediators.py

Mediator is ,like its name says , mediated Views/Component. Its the first contact point of GUI to the application control.
puremvc.patternts.mediator.Mediator has attribute named viewComponent which essentially holds the reference of View class which its mediating. In our example only one view require one mediator,defined in Mediator.py file.
MainFrameMediator  class has three important overridden methods , onRegister,listNotificationInterests and handleNotification.
onRegister is called when the view is activated and its mediator is instantiated soon after the view activation/instantiate. Here is good place to register/Bind the events from GUI or views class. Also in our example we are retrieving proxy model from facade.
listNotificationIntrests , returns the list of application context level events , which this mediator would like to be notified, here we are returning only one event ApplicationFacade.DATA_CHANGED , which will be fired when proxy will change its model and notify the Facade about the change.
Now when this event is notified , mediator's handleNotification will be called . This method will receive notefication class object as its parameter.
Here we have only one Notification named DATA_CHANGED , but in case of multiple interests,we simple perform if-else or switch statement to check agains notification.getName() property, and call appropriate method.

Model.py

In pureMVC framework , the model is represented as puremvc.patterns.proxy.Proxy class. The proxy class object contains a property vo , ie Value Object , which is simple data object . Proxy is responsible to load/save/deliver this data object. For example proxy can get data from remote location and save to its vo.
Here we have only one proxy classs, UserProxy .It has vo of type UserVo.

Vo.py

Contains only one clase UserVo , which has only one property info .

Running Application

Running Application
Here is the snapshot of the running application. 
When user clicks the Click Me Button , the text from TextCtrl is send to Mediator , this mediator then updates the proxy model , which it has local reference to.
The proxy model data is changed and it fires another notification to the Facade,telling that data has changed. Facade notifies every Mediator or Commands , which are registered to that notification. Our single mediator is "interested" in this notification , so it handleNotification  and updates the StaticText value of its viewComponent . Sounds Simple and worthless? Wonder not , this kind of flow/pattern becomes useful and manageable in a more complex application. I don't know whether people use Python other than prototyping :)

Here is the the files for the application, just copy all in the SRC  folder of the pyDev project.

Download Source File

 

No comments:

Post a Comment