Thursday, May 29, 2008

Creating a message box dialog with PyGTK and Glade

Being a newbie to Python, GTK and Glade, I found it rather enjoyable developing stuff fast and easily with this language/library/tool combination. All you need to do to get a GUI up and running is to "draw" it with Glade and connect it with pygtk.

What makes it not so perfect is that there's hardly any systematical material online to tell folks how these great things works together. I could only find some separate pieces of information here and there about this, as I wrote before. Fortunately these pieces information are all great. So I highly recommended those absolute beginners to read this essay, to say the least, to get things started.

Here I'm going to show the way to create a message box, which is probably the most (simple?) commonly used dialog in a GUI. It has a OK button and displays a message you passed. Like this:

When you use it, simply create a instance and pass the message (and the title of the dialog if necessary) to it:

1 from msgBox import messageBox
2 messageBox('Guess what? I am a message box!')


How does that look?

First of all, let's draw the message box out. This is really easy:

Open Glade2, find "dialog" in the palette and click it. Choose "Standard Button Layout", "OK". After the dialog shows up, click "label" on the pallette and then click on the blank area in the previous dialog window.

Next, we are going to set up the signals. Thanks to glade, this part becomes so simple in our case that all we need is click the OK button (or, notice that you can always go to View->Show Widget Tree to focus on the widget you are looking for). In the Properties window, choose "Signals" tab, click on the "..." button after "Signal" entry. Find "clicked" and click "OK". Now don't forget to click "Add" afterwards.

Notice that here we are using mostly default names: dialog1,okbutton1,label1,etc. And you can always choose your own.

Now save the project and quit, I name it "msgBox". And you should get a new folder named the same as the project and two files with the name plus suffix .glade and .gladep. If you try to open them with a editor, you will find them just XML files that represent the widget trees and the properties of each widget we created.

Now type in the following script in a editor and save the file as msgBox.py (line number not included, of course), I'll explain it line by line.
msgBox.py

 1 try:
 2         import pygtk
 3         pygtk.require('2.0')
 4         import gtk
 5         import gtk.glade
 6 except:
 7         print 'Install pygtk,libgtk2.0 and libglade2.0'
 8         import os
 9         os.exit(1)
10
11 class messageBox:
12         def __init__(self, lbl_msg = 'Message here',
13                         dlg_title = ''):
14                 self.wTree = gtk.glade.XML('msgbox.glade')
15                 self.dlg = self.wTree.get_widget('dialog1')
16                 self.lbl = self.wTree.get_widget('label1')
17                 self.dlg.set_title(dlg_title)
18                 self.lbl.set_text(lbl_msg)
19                 handlers = { 'on_okbutton1_clicked':self.done }
20                 self.wTree.signal_autoconnect( handlers )
21
22         def done(self,w):
23                 self.dlg.destroy()

Line1-9 imports the modules we need. If you've checked the recommended essays in the beginning, you shouldn't have problems with these lines.

The rest of the code defines a class that calls up our message box dialog.

Line 12-13: We pass two arguments to the __init__ method: the message you are going to display and the title of the the dialog window.

Line 14: this is the highlight of the whole point. The method gtk.glade.XML takes the XML file we created with glade, parses it and creats gtk.glade.XML object( which has the widgets tree and some methods ) accordingly.

Line 15-16 uses the gtk.glade.XML method get_widget to fetch the references of the widgets, whose names are passed as arguments.

Line 17, as you may guess, sets the title of the dialog window to the name we assigned.

Line 18 sets the message.

Line 19-20: remember the signal we set for the OK button? here we bind the signal and its handler in a dictionary and pass it to the method gtk.glade.XML.signal_autoconnect. That means when the GUI releases the signal "on_okbutton1_clicked" (which happens when the OK button is clicked, obviously), the program will call the corresponding method( self.done ).

Line 22-23: defines the method done, which is our handler of the signal "on_onkbutton_clicked". It does one thing: call the destroy method, which will terminates the dialog.

A little summary here: we created the GUI object according to the XML files, set up the message we intended to play and make the "OK" button destroys the dialog.


Now you get msgBox.glade, msgBox.gladep and msgBox.py. Whenever you need a message box in your application, just copy them to your package and take advantage of it as introduced in the beginning. The following is a package of all the files described before as well as a simple example of using the class:

http://code-of-danmarner.googlecode.com/files/msgBox.zip

No comments: