2.10.2 Using Proxies

As stated before, Proxies attempt to reduce the "glue" code between UI and domain object. They work by attaching themselves to the model, detecting the widgets in the interface, attaching the correct signals to these widgets, and providing handlers that manipulate the attached model in a standard way. The updating mechanism works by associating selected widgets in the Proxy to attributes in the model; if the model offers accessors to these attributes, they will be called, and otherwise direct manipulation of the model attributes is performed. This association is done by name: the names of the widgets determine the name of the accessors or attributes that will be used in the model.

There are three types of Proxy classes: SlaveProxy, Proxy and GladeProxy. Their constructors are similar to their Delegate counterparts, the main difference being a new parameter, model, which specifies the instance that we should attach this proxy to. The Proxy's widgets list uses an extended syntax: the widget names that are to be associated to attributes should be prefixed by a single colon character (:). This prefixing should be done *only* in the widgets list - the name in the glade file, the model and the callback syntax should not include it.

For the first example, let's attach a proxy to an interface specified in glade (examples/NewsForm/newsform.py):

Let's look at this simple example. First, I define a model class which is really just a shell class, with no methods or attributes: NewsItem. We create an instance of this class, define the widgets list (that will correspond to the model attributes), and create a new proxy, specifying item in the constructor.

After running the Proxy, there is a print call that outputs the attributes from the item instance. Note that these attributes were not defined initially in the model: this is not a problem; the proxy will set them to sensible values on startup. If you run the program, enter data in the entries, and close the window, you will also see that the values printed out at the end correspond to the values typed in.

Note that we don't need to define any handlers for the Proxy's widgets. This is the Proxy's "magic" - it defines internal handlers that take care of updating the attached model automatically. As we insert and delete text from the entries, the model is being transparently updated to reflect the new value in the interface. In this way, the interface's state is synchronized with the model's state.