Create User Interfaces with Glade

Mitch shows how to use gnome-python's libglade binding to build Python-based GUI applications with little manual coding.

GladeBase.UI corresponds to the View component of the MVC design pattern. It is responsible for creating a widget hierarchy from a Glade project file and for updating the visual content of an application under direction of an associated controller. GladeBase.UI is derived from libglade's GladeXML class, so it inherits all of the methods discussed earlier.

The GladeBase.UI constructor takes three arguments: the filename of the Glade project file from which it will load its widget hierarchy, the name of the widget that serves as the root of the hierarchy and an optional keyword argument, gladeDir, which is the relative pathname of a directory in which to look for Glade project files.

The gladeDir keyword argument defaults to the current working directory. It is joined with the filename argument to form the relative pathname of the Glade project file.

It may seem odd to use both gladeDir and filename parameters instead of specifying the location of the Glade project file with a single relative pathname. But this separation can reduce maintenance costs for any application that stores its Glade project files in a single subpackage.

Such an application can define a subclass of GladeBase.UI, which provides a hardwired value for gladeDir:

import GladeBase
class UIBase(GladeBase.UI):
  def __init__(self, filename, rootname):
    GladeBase.UI.__init__(self, filename, rootname,
class MainWinUI(UIBase):
  def __init__(self):
    UIBase.__init__(self, "", "window1")

Then the application can derive all of its UI classes from this subclass. In this way the application can specify in one place the relative pathname of the directory containing all of its Glade project files.

A helper module,, enables GladeBase.UI to search the Python path for files. The PathFinder.find function takes a pathname as its sole argument. If the pathname is absolute, it is returned without further processing. If it is a relative pathname, the find function joins it with each Python path entry in turn to create a candidate pathname. If the candidate pathname exists, it is returned. If no candidate pathname matches, find raises a PathFinder.Error exception (see Listing 2).

Listing 2.

The GladeBase.UI.__getattr__ method makes it possible for clients to access the widgets in a GladeBase.UI hierarchy as though they were attributes of the instance. The __getattr__ method assumes that the attribute name provided by the caller is the name of a widget and looks up the widget using GladeXML.get_widget. Once the widget is found, it is cached as a new instance variable to speed up future access. If the requested widget can't be found, __getattr__ raises an AttributeError.

If a widget hierarchy contains more than one widget with the same name, there's no telling which one will be returned by GladeBase.UI. When you're using GladeBase.UI it's a good idea to name widgets the same way you would name Python instance attributes: each name should be unique to the object and should be a valid Python identifier.

Application-specific UI classes usually extend GladeBase.UI with methods to perform complex user interface updates.


GladeBase.Controller corresponds to the Controller component of MVC. A Controller responds to user input events by translating them into changes in the state of the application data model. Similarly, it responds to changes in the data model by translating them into UI updates.

GladeBase.Controller doesn't help you respond to changes in your application's data model, but it does automatically wire up signal handler methods to the signal handlers defined in a Glade project file.

The GladeBase.Controller constructor takes one argument: an instance of GladeBase.UI that is the UI to be controlled. During initialization, a new GladeBase.Controller instance traverses its class hierarchy, building up a dictionary of all callable objects in the instance's namespace (the traversal starts with the instance dictionary in case any callables have been defined as instance attributes). GladeBase.Controller then passes this dictionary to the signal_autoconnect method of the supplied GladeBase.UI instance.

Application-specific controller classes extend GladeBase.Controller simply by defining signal handler methods:

class Controller(GladeBase.Controller):
    def __init__(self, ui):
        GladeBase.Controller.__init__(self, ui)
    def on_window1_delete_event(self, *args):
    def on_button1_clicked(self, *args):
        print "Button 1 clicked."