Using MVC when the model is dynamic

Mitch Chapman mitchchapman at earthlink.net
Wed Oct 1 11:11:49 EDT 2003


pysim wrote:
> Hi, I have a couple of general requests for pointers to python
> examples and design advice.
> 
> I'm looking for examples of MVC-based GUI controls done in python
> (model-view-controller).
> 
> Also, examples where something like a simulation model running in its
> own thread sends fast updates to a GUI in near real-time.  The only
> examples I've seen, such as SimPy, wait until the model is finished
> running before outputting data.
> 
> Most MVC controls I see in java for example are only designed for
> infrequent user-driven changes, like resizing a window or mouse
> clicks, not cases where the underlying model is changing itself over
> time.

Here's a baroque example.  Maybe it will inspire others to respond
with something more concise :)

The attached example app has a text-based "GUI", as I wanted it to
be more or less self-contained.  The app prints a sinusoidal
line of "#"s, until you type "q" and hit return.  E.g.

#
#
   #
       #
           #
              #
                  #
                    #
                     #
                    #
                  #
              #
...

The classes in the example include:

Observable -- maintains a set of observers, notifying them whenever
the value of the Observable changes.

Model -- runs a simple computation in a background thread.  The
Model's state is an Observable.

View -- displays a model's state as shown above.  Also processes
keyboard input, looking for a line starting with 'Q' or 'q' as
a shutdown request.

App -- acts like a controller, but also includes the application's
main event loop, which blocks until keyboard input is available.


The Model and View know nothing about each other.  The
App glues them together; it tells the View to update whenever
the Model state changes.  It also routes user input (keyboard
input, in this case) to the View.  This is a common way
to build MVC applications, and it addresses your concern about
controls which are designed only for user-driven changes.


There's a lot of synchronization overhead in updating the view.
If you have lots of views on the same model, or if your views
take a long time to pain, performance and responsiveness will
suffer.  In such cases it might be good to have the model publish
its state only at regular intervals -- store its current state
in a protected attribute and only occasionally copy that state
into an Observable.

Or, if you want to write really baroque code (like me,
apparently :) you could use a "delayed" Observable which
propagates model state changes at low rates.  For example, the
model might publish its state using an instance of this
(untested) class:

class DelayedObservable(Observable):
     ...
     def __init__(self, notifyInterval=1.0):
         self._tLastChange = time.time()
         self._notifyInterval = notifyInterval  # Seconds

     def _notify(self, force=0):
         dt = time.time() - self._tLastChange
         if force or (dt >= self._notifyInterval):
             for observer in self._observers:
                 ...
             self._tLastChange = time.time()


This is all pretty verbose, but maybe it will be helpful.

For better ideas on limiting the rate of propagation of model
state changes, it might be good to look at the documentation
for NSNotificationQueue.  It's part of the Cocoa framework of
Mac OS X.

--
Mitch
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: MTMVCExample.py
URL: <http://mail.python.org/pipermail/python-list/attachments/20031001/eced2bb1/attachment.ksh>


More information about the Python-list mailing list