含有章节索引的中文 文章模板

::-- ehu4ever [2005-09-15 05:42:00]

1. Using libGlade with Python

Libglade is a library that reads in an XML file and makes the corresponding calls to GTK to create a GUI. Glade (actually Glade-2. exe or glade2) will present you with a GUI for creating these XML files. There are many advantages for doing your GUI in this way:

  • You can change your GUI quickly and easily.
  • You can have multiple GUIs that drive the same underlying application.
  • You spend your time designing the GUI, and not debugging the GUI creation code.

As Immunity developed CANVAS, we also strove as much as possible to isolate the code from the GUI altogether. Although we liked the pyGTK model, there was a distinct possibility that someday we would want to port to a platform that GTK did not support, such as the Sharp Zaurus. Good application design specifies that you actually build another layer in between your GUI and your application code, such that you have three layers:

  • The XML file that describes your GUI.
  • An application file (called something like mygui . py), which loads the GUI and application, and other application files as needed for major GUI components to allow for testing them independently of the rest of the application. These are the only files that use GTK functionality directly.
  • The application logic itself, which should never import GTK or any GUI toolkit library. All calls to the GUI should be through the code in mygui . py.

Using this design will save you years of time later trying to debug some small threading error. All of Immunity CANVAS (not a trivial application) was ported from GTK version 1 (and pyGTK version 1) to GTK version 2 (and corresponding pyGTK) within one day. Because GTK development is proceeding quite quickly, this sort of capability is going to be key to maintaining compatibility with the library itself.

2. A Glade Walkthrough

If you've never used a GUI builder, then you can't fully appreciate how easy Glade has made the whole process. If you have, you'll find that Glade offers the same kind of features you're used to.

2.1. Starting Glade

Start glade by running glade-2. exe, or on Unix-like systems (including Mac OS X), a simple glade or glade-2 will do. Glade starts up with three windows: a project window as in Figure 13-6, a palette of widgets you can use to build your GUI as in Figure 13-7, and a property sheet displaying information on the currently selected GUI widget as in Figure 13-8. Because you have no GUI widgets yet, the property sheet is blank.

Figure 13-6

Figure 13-7

2.2. Creating a Project

First, start a new Glade project called GladeTwoButtonsGUI.

Glade might ask you some questions at this point, but your answers don't matter much. Glade might offer you options for two types of projects: GTK or Gnome projects. A Gnome project would use features unique to the Gnome desktop environment, which is usually available on Linux, but is not a good idea for cross-platform projects. You want something portable, so choose a GTK project instead. If Glade asks you to pick a language (for instance, C, C++, or Ada), choose any of them; it doesn't matter. You're not generating the GUI code from Glade, You're going to be using only the XML file that Glade generates to describe the GUI layout.

Save your project now, and you can start creating a GUI with the palette.

2.3. Using the Palette to Create a Window

The Glade widget palette is one of the most important tools you'll be using. You can see an image of the palette in Figure 13-9. Each icon on the palette corresponds to a type of widget or widget container. To create a widget, you click its icon and then the container in which you want to place that widget.

Of course, you don't start out with anywhere to put any of the widgets. Let's change that by creating a new window. Click the top-left icon on the palette (it's called Window and it looks like a little empty window) to create a root window for your application.

Figure 13-9

The Window and Dialog widgets are top-level widgets: They have their own GUI windows and they don't need to go into a widget container. Every other widget in your application will have a Window widget or a Dialog widget as its ultimate parent.

This window starts out with the name of "window1," but you can change this from its property sheet. You'll find that Glade selects names for each widget based on a simple incrementing number plan. The first text view widget you create is called "textview1", the first window is "window1", and so on. If you hover over an icon on the palette, or click to select it, Glade will tell you what kind of widget that icon represents.

2.4. Putting Widgets into the Window

The window you just created provides a container in which you can place a widget (or another container). Let's use this to recreate the two-button GUI from the earlier example.

Recall that a window can only contain one child widget. Before you can place any buttons, you need to fill the window with a box: a virtual widget that can contain multiple child widgets. Click the Vertical Box icon on the palette and then click on the window to place a vertical box in the window. You'll be asked how many rows you want in the box. Because you're going to place two buttons, enter 2. Now you have a window that contains a vertical box (see Figure 13-10), which itself can contain up to two widgets.

The presence of the vertical box is denoted graphically by a white line partitioning the window into two parts. When the GUI is actually run, though, all you'll see are the widgets inside the vertical box. Remember that virtual widgets such as boxes don't show up in the GUI; they just determine how the other widgets appear.

Let's put buttons in the box. Click the Button icon on the palette and then click on the top partition of the vertical box. Repeat this to put another button in the bottom partition of the box. Resize the window if necessary, and you should have something that looks almost like our other two-button example (see Figure 13-11).

Figure 13-10

Figure 13-11

Use the properties sheet for each button to change its label, and the illusion will be complete (see Figure 13-12). If you can't find the window with the properties sheet, select View ~ Show Property Editor in the main Glade window to make it show up.

Figure 13-12

By setting these properties, you'll get a window with two buttons that have changed according to the text you've entered (see Figure 13-13).

Figure 13-13

2.5. Glade Creates an XML Representation of the GUI

It should already be clear how powerful Glade is. With it, you can construct a GUI visually instead of by writing code. But how do you get this GUI into a representation that Python can understand?

Save your Glade project, and then look in the project's directory. You should find a GladeTwoButtonsGUI. glade file that contains an XML representation of the GUI you just created. That XML representation will look something like this (although a lot of it has been edited out for clarity):

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="window1"> 
<child>
<widget class="GtkVBox" id="vbox1"> 
<child>
<widget class="GtkButton" id="button1">
<property name="label" translatable="yes">Hello World</property>
</widget>
</child>

<child>
<widget class="GtkButton" id="button2">
<property name="label" translatable="yes">Hello Again</property>
</widget>
</child> 
</widget> 
</child>
</widget>

</glade-interface>

If this looks like gibberish to you, consult Chapter 15 for more information on XML. If you can read XML, notice that this data structure defines a tree of tags that corresponds to the tree structure of the GUI. The interface as a whole contains a window (GtkWindow), which contains a vertical box (GtkVBox), which contains two buttons (GtkButton). The buttons have customized label properties, just as you defined them in Glade.

In short, this XML file contains the same information as the GUI we defined visually, and the same information as the several lines of Python we used to define the same GUI in TwoButtonsGUI. py. If there were a way to get Python to parse this file and create a GUI out of it, we could save a significant amount of code. This is where libglade comes in.

Try It Out: Building a GUI from a Glade File

libglade parses the XML file and makes GTK widgets corresponding to the widgets described in the XML file. Here's GladeTwoButtonsGUI. py, a version of TwoButtonsGUI. py that loads its GUI from the XML file instead of using a series of Python statements:

   1 #!/usr/bin/env python 
   2 import findgtk
   3 import gtk.glade
   4 
   5 class TwoButtonsGUI:
   6         def __init__(self) :
   7 self.window = gtk.glade.XML('GladeTwoButtonsGUI.glade', 'window1')
   8 
   9 if __name__ == '__main__':
  10         TwoButtonsGUI()
  11         gtk.main()

How It Works

This program uses libglade to load a set of GUI widgets from the GladeTwoButtonsGUI. glade file we created with Glade. The GUI looks just the same as the Glade mock-up, and the same as we created with pyGTK calls in the TwoButtonsGUI. py program. The advantage over the original TwoButtonsGUI. py is that we had to write a lot less code to get the same GUI.

Glade greatly simplifies the layout of even small GUIs. As you'll see, it also provides a framework for designating which events a GUI is expected to handle.