next up previous contents
Next: Module adapters Up: Adapters Previous: Introduction   Contents

What are Adapters

Adapters are the generalization of the the code that handles autonomously the connection between a set of widgets and a corresponding set of properties (possibly observable) to keep aligned automatically the logical and the presentation sides, and to keep low the complexity of controllers.

Figure 7: Schematic simple adapter
Image adap

In figure 7 is represented a simple adapter, where main internal functional blocks are shown. There exist functional blocks to control (and possibly customise) the way the property and the widget are read and written. Also, there is a functional block to manage how errors are handled when exceptions occur when writing into the property.

An Adapter adapts widgets and model's properties. Adapters offer strong customization, but in their simplest use they are pretty easy to be used. In this context, previous example might be handled as follows.

We have a hand-made View containing a button and a text entry. Notice that the name of the text entry is entry_text.

class MyView (gtkmvc.View):
    def __init__(self, ctrl):
        gtkmvc.View.__init__(self, ctrl, register=False)

        w = gtk.Window(); e = gtk.Entry(); b = gtk.Button("Press")

        h = gtk.VBox(); h.add(e); h.add(b); w.add(h)
        w.show_all()
        self['entry_text'] = e
        self['button'] = b
        
        ctrl.register_view(self)
        return
    pass # end of class

The model contains an observable property that should always reflect the content of the text entry entry_text.

class MyModel (gtkmvc.Model):
    __properties__ = {
        'text' : "Ciao",
        }
    pass # end of class

As usual, the controller is the most complex part, but by exploiting an adapter it gets pretty much simplified.

class MyCtrl (gtkmvc.Controller):
    def register_adapters(self):
        self.adapt("text")
        return

    def register_view(self, view):
        gtkmvc.Controller.register_view(self, view)
        view['button'].connect('clicked', self.on_button_clicked)
        return

    # signal handles
    def on_button_clicked(self, button):
        print "Text is:'%s'" % self.model.text
        return

    pass # end of class

The idea in this example is to have ``button'' that when pressed makes model's observable property text printed out to the standard output.

No code is included to handle entry_text ``change'' signal and observable property value change notifications. Instead, a new method surfaces off the controller: register_adapters.

This method is called at the right time by the framework and it is a good place where adapters can be created and connected. In the example, creation occurs through a call to another new method of class Controller: adapt.

The new method is pretty complex and will be discussed in depth later. Enough to say now that parameter "text" represents the name of the observable property that we want to adapt. The corresponding widget is searched among all widgets in the view, and widget entry_text is found and connected automatically. The way this magic happens is not important at this stage, but soon you will introduced with all details, to make you know how to fully exploit and control this new feature.

Figure 8: Simple adapter at work
Image adap1

The code that instantiates and runs this example is as usual:

m = MyModel()
c = MyCtrl(m)
v = MyView(c)
gtk.main()

File examples/adapters/simple.py contains the full source code of this example. When being run, it shows up a window containing the text entry and the button. When the button is pressed, the content of the observable property text is printed to the standard output. Initially, text is assigned to "Ciao" and the text entry reflects it accordingly.

If the user changes the text in the entry, the property text will be changed accordingly, as it is easy to check by clicking the button. Viceversa, if the property text were changed by another model, observer, etc., the text entry would get updated accordingly.


next up previous contents
Next: Module adapters Up: Adapters Previous: Introduction   Contents
Roberto Cavada 2008-08-26