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

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,
                          gladeDir="MyApp/GladeFiles")
class MainWinUI(UIBase):
  def __init__(self):
    UIBase.__init__(self, "main_win.glade", "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, PathFinder.py, 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. PathFinder.py

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

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):
        gtk.mainquit()
    def on_button1_clicked(self, *args):
        print "Button 1 clicked."
______________________

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState