MVC Help

Fredrik Lundh fredrik at pythonware.com
Tue Jan 17 07:29:02 EST 2006


"Sbaush" <sbaush at gmail.com> wrote:

> The View must be only the clickable button
> The Control must be the event listener on the button
> The Model must be the action of the button.

> If we can complete this MVC simple implementation we could publish this like
> a "MVC SIMPLE TUTORIAL" because with only a button this could explain the
> MVC Observer based Architecture.

if you think that an "action" is a good model, you've probably already lost track
of what MVC really is.

if you want something simple, I suggest using a simple model that's updated by
a simple user action.  here's a straightforward WCK example, which uses a click
counter as the model.  note that the test script creates a single model instance,
and displays it in multiple views.

from WCK import Widget, Controller, Observable
from WCK import FOREGROUND, FONT # platform default

class MyModel(Observable):

    count = 0

    def increment(self):
        self.count += 1
        self.notify(None) # notify observers

class MyController(Controller):

    def create(self, handle):
        handle("<ButtonRelease-1>", self.handle_button_release_1)

    def handle_button_release_1(self, event):
        # update the model
        model = event.widget.model
        if model:
            model.increment()

class MyView(Widget):

    model = None
    ui_controller = MyController

    def _notify(self, event, data):
        # called by the model via the observable mixin
        self.ui_damage() # update myself

    def setmodel(self, model):
        # install new model
        assert isinstance(model, Observable)
        if self.model:
            self.model.removeobserver(self._notify)
        self.model = model
        self.model.addobserver(self._notify)

    def ui_handle_repair(self, draw, x0, y0, x1, y1):
        # repair widget contents
        if not self.model:
            return
        font = self.ui_font(FOREGROUND, FONT)
        text = str(self.model.count)
        draw.text((10, 10), text, font)

    def ui_handle_destroy(self):
        # cleanup (called when the widget is destroyed)
        if self.model:
            self.model.removeobserver(self._notify)

if __name__ == "__main__":
    # try it out

    from Tkinter import Tk

    root = Tk()

    model = MyModel()

    view = MyView(root, background="light blue")
    view.pack(side="left")

    view.setmodel(model)

    another_view = MyView(root, background="light yellow")
    another_view.pack(side="left")

    another_view.setmodel(model) # shares the same model!

    if 0:
        # enable this to illustrate external updates to the model
        def tick():
            model.increment()
            root.after(1000, tick)
        tick() # start ticking

    root.mainloop()

</F> 






More information about the Python-list mailing list