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 two types of Proxy classes: Proxy and
ProxyDelegate. 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.
#!/usr/bin/env python import gtk from kiwi.ui.gadgets import quit_if_last from kiwi.ui.views import BaseView class NewsItem: """An instance representing an item of news. Attributes: title, author, url, size""" title = '' url = '' author = '' size = 0 item = NewsItem() my_widgets = ["title", "author", "url", "size"] view = BaseView(gladefile="newsform", widgets=my_widgets, delete_handler=quit_if_last) view.add_proxy(item, my_widgets) view.focus_topmost() view.show() gtk.main() # runs till window is closed as per delete_handler print 'Item: "%s" (%s) %s %d' % (item.title, item.author, item.url, item.size)
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.