PyGnome/PyGTK/Libglade Tutorial

Note: this document is a work in progress and not yet complete.

Table Of Contents

  1. Reasons for Using PyGnome/PyGTK/Libglade
  2. Requirements
  3. Hello World
  4. Simple GNOME Application
  5. ...
  6. Useful Links
  7. Credits / Thanks

Hello World

First, start up Glade. From the Palette, select a Window from the GTK Basic menu. You should now see something like this:

Next, select a label and "paint" it into the window by clicking on the crosshatched surface. In the Properties window, simply change the Label value from "label1" to "Hello World"

The important thing to remember from the Properties window is that the name of this Label widget is "label1", in case you want to access or change that widget.

Next, we'll need to add a signal for the destroy event of window1. We have to do this because we want to tell the program to quit when we destroy the window. Otherwise the program will keep running and we would have to kill it by hand. Select the window1 widget, then in the Properties window, select the Signals tab. Click the elipses button, and select the destroy signal. Glade will automatically suggest a name for the handler, "on_window1_destroy", which is fine for our purposes. Click the Add button and we've made our app listen for the destroy signal. When this signal arrives, it will call the on_window1_destroy function, which we will define in python.

Now simply save the project and we're done with the Glade component. Go to the directory where you saved your glade file (mine was "~/Projects/project1"), and create a new python file called hw.py.

#!/usr/bin/python
from gtk import *          #---------
from gnome.ui import *     # Import necessary modules for this tutorial
from libglade import *     #---------


#----------------
# DestroyFunction
# this function is called when the window gets destroyed
#----------------
def DestroyFunction(obj):
	mainquit()


widgetTree = GladeXML("project1.glade")   #create a widget tree from a glade
                                          #file, also does the work of showing
					  #the window

dic = { "on_window1_destroy" : DestroyFunction } #maps signal handlers

widgetTree.signal_autoconnect (dic)       #connects signal handlers defined in
                                          #the glade file to actual Python
                                          #functions

mainloop ()


Now simply make hw.py executable (chmod +x hw.py) and run hw.py. You should see a window that says "Hello World".


Downloads

Download
project1.glade (glade UI file)
Download hw.py (python program)

Simple GNOME Application

Now we'll take a look at making a GNOME application. The first step is very similar, we just choose a GNOME Application Window from the menu instead of a GTK Window. As you can see, this starts us off with a few more bells and whistles than the simple GTK Window. We've got a standard menubar with "File", "Edit", "View", "Settings" and "Help", we've got a toolbar with "New", "Open", and "Save" buttons, we've got a blank crosshatched area like before, and we've got a statusbar down at the bottom.

Let's put a notebook in our window. From the GTK menu, select notebook, and paint it into the crosshatched area. We don't need all three pages (we'll dynamically add and subtract some later), so just add 1.

You should now see one notebook tab with a crosshatched area inside it. Just to keep things simple, paint a label inside this area.

Next, add a signal to handle the destruction, just like we did before. That will finish off the Glade component stuff for now (As an exercise, you can change "project1.glade" to "project2.glade" in hw.py, run it and see what happens). Let's make our application slightly more complicated than Hello World. All applications manage/manipulate/display some kind of data. Because we're using Python (as in Monty), let's manage some data about Silly Walks. We'll create a simple data structure to hold information about Silly Walks:

class SillyWalk:

	def __init__(self, cost, speed, desc):
		self.researchCost = cost
		self.speed        = speed
		self.description  = desc

We're going to cheat a little bit, and not write Get...() and Set...() functions for this class, seeing as it is so simple, and this is merely a tutorial. When needed, we'll just access the attributes directly.

One of the things we are going to do properly is separate the user interface from the logic of the application. By using the LibGlade approach, we're halfway there (our static UI specification is in a separate file from our code). To fully realize this goal, we'll take some inspiration from the Model / View / Controller pattern, and create a View class whose only job is to alter what is seen by the user. One of the main advantages of this is that the application can have multiple View classes (ie, GnomeView, KDEView, TextView, SDLView, Win32View), and use the most appropriate one.

class GnomeAppView:
	def __init__(self, specFileName="project2.glade"):
		self.specFileName = specFileName
		self.widgetTree   = None

	def Show(self):
		self.widgetTree = GladeXML( self.specFileName )
		dic = { "on_window1_destroy" : self.Destroy } 
		self.widgetTree.signal_autoconnect (dic)

	def Destroy(self, obj):
		mainquit() #make the program quit

This is the only class that knows how to display the user interface and respond to callbacks from it. You'll notice a lot of similarity with our previous Hello World script. When Show() is called, the application window displays. We've hooked the on_window1_destroy signal to the GnomeAppView object's Destroy() method. When Destroy() gets called, the program terminates.

Now we'll add a class to hold multiple Silly Walks and some commands to start up the program. Here's the full source code:

#!/usr/bin/python
from gtk import *          #---------
from gnome.ui import *     # Import necessary modules for this tutorial
from libglade import *     #---------

class SillyWalk:

	def __init__(self, cost, speed, desc):
		self.researchCost = cost
		self.speed        = speed
		self.description  = desc


class GnomeAppView:
	def __init__(self, specFileName="project2.glade"):
		self.specFileName = specFileName
		self.widgetTree   = None

	def Show(self):
		self.widgetTree = GladeXML( self.specFileName )
		dic = { "on_window1_destroy" : self.Destroy } 
		self.widgetTree.signal_autoconnect (dic)

	def Destroy(self, obj):
		mainquit() #make the program quit


class SillyWalkApp:
	def __init__(self ):
		self.view         = GnomeAppView( )
		self.walks        = []

	def Start(self):
		self.view.Show()
		mainloop ()

myApp = SillyWalkApp()
myApp.Start()


Save this as gnome-simple.py, make it executable and run it. You should see something like this:

Downloads

Download project2.glade (glade UI file)
Download gnome-simple.py (python program)

Dynamic User Interface



Here is the reference documentation for GtkNotebook.

Useful Links

The Whole PyGTK FAQ
Robert Laing's Writing Gnome Applications With Glade and Python
John Finlay's PyGTK Tutorial
Hilaire Fernandes' Developing GNOME Application with Python
Daniel Kornhauser's PyGNOME Tutorial

Credits / Thanks