Creating a GUI using PyGTK and Glade

After spending some time creating a GUI using TKinter and having it be pretty easy, but getting frustrated by how linked my code and the GUI was, I decided to look into creating a GUI using another toolkit. After looking around at the options for a while I settled on using PyGTK and Glade

The reason I decided upon using these two technologies is because they are cross platform and using GLADE satisfies my wish to separate the code form the GUI.

If you’ve never heard of Glade before, it’s “a User Interface Builder for GTK+ and GNOME”. It generates XML files which describe the desired GUI.

I’ll let the pyGTK website describe what PyGTK is:

PyGTK provides a convenient wrapper for the GTK+ library for use in Python programs, taking care of many of the boring details such as managing memory and type casting. When combined with PyORBit and gnome-python, it can be used to write full featured Gnome applications.

So there you go, I’m writing this on my freshly installed Debian system. If you are running Debian, or a Debian based distribution getting PyGTK and Glade is pretty simple:

apt-get install python-gtk2 python-glade2

Now lets create our first simple GUI, this is what you will be greeted with when you first start GLADE:

Python RSS Reader

What we need to do is press the “Window” button on the GLADE palette to create our base window. We can then edit the properties of the window in the Properties Window:

Python RSS Reader

We’ll call our window MainWindow and we will set the title to be “Hello World… Again!”.

If you are used to using an integrated GUI builder, for example Visual Studio, using glade might feel a bit strange the first few times. Especially since you don’t actually place your controls anywhere you want on the screen, instead you “pack” them. Strangely enough (at least for me) it actually seems like this is the way the most GUI builders work and applications like Visual Studio are actually the odd ones.

Either way back to the tutorial, the first thing we are going to do is add a label to tell the user to click the button (of course we could just put this text on the button, but how much fun is only one widget?). Since GTK used containers to pack widgets the first thing that we need to do is add a container. We are going to place the label above the Button so we will use a Vertical Box with two rows. To add the vertical Box, simply click on it in the Glade Pallet, and then click on our main window. A small dialog will come up and ask you how many rows you want, we want two in this case.

The next thing we’ll do is add the label by clicking on the label button in the GLADE pallet and then click on the first row in the container that we just created. We’ll keep the default name (label1) but we will change the text to be: “Please click on the button!”. Changing the text is done in the Glade Properties window, which if you have not noticed by now, displays, and allows you to edit, the properties of the currently selected widget.

The next thing we’ll do is add a button in the same way that we added the Label widget except we will add it in the second row. We will call the button btnHelloWorld, and set it’s label to be “Click me!”

We now need to set our project options, I’m going to call this project “pyhelloworld” and save it in my projects/PyHelloWorld folder.

Python RSS Reader

Note: Be sure to set the Visible option for the MainWindow to Yes, on the Common tab of the Window or your main window won’t be visible! This is especially important if you are using Glade3!

So that’s it, you’ll see in the PyHelloWorld folder, that two files have been created, one is the glade project file and has the .glade extension, and the other is our glade GUI XML file with the extension .gladep.

Now we need to create a python program that will load the glade file and display it. So in the same folder I am going to create a file called PyHelloWorld.py.

PyGame Window

Now the first thing we are going to have to do is import all of the libraries that we need for our project:

#!/usr/bin/env python

import sys
try:
 	import pygtk
  	pygtk.require("2.0")
except:
  	pass
try:
	import gtk
  	import gtk.glade
except:
	sys.exit(1)

The next thing that we need to do is create our main class, I’m going to call it HellowWorldGTK. The we will use the __init__ function to load our glade file:

class HellowWorldGTK:
	"""This is an Hello World GTK application"""

	def __init__(self):
		
		#Set the Glade file
		self.gladefile = "pyhelloworld.glade"  
	        self.wTree = gtk.glade.XML(self.gladefile) 
		
		#Get the Main Window, and connect the "destroy" event
		self.window = self.wTree.get_widget("MainWindow")
		if (self.window):
			self.window.connect("destroy", gtk.main_quit)

The first thing that we do (after defining the class) is specify the glade file that we are going to use and create a gtk.glade.XML object using our glade file. Here is a description of the object taken from the pyGTK2 reference:

This object represents an `instantiation’ of an XML interface description. When one of these objects is created, the XML file is read, and the interface is created. The gtk.glade.XML object then provides an interface for accessing the widgets in the interface by the names assigned to them inside the XML description.

The gtk.glade.XML object can also be used to connect handlers to the named signals in the description. Libglade also provides an interface by which it can look up the signal handler names in the program’s symbol table and automatically connect as many handlers up as it can that way.

So what we are doing when we create our gtk.glade.XML object is creating and loading our main interface.

The next thing that we go is get an instance to our main window and connect the “destroy” event with the get.main_quit() function. This basically quits our application when the main window is closed. Otherwise the application will continue to run when the main window is closed (which we obviously don’t want).

That’s it for our HellowWorldGTK class, the next thing that we need to do is create an instance of our class and then start the GTK main loop:

if __name__ == "__main__":
	hwg = HellowWorldGTK()
	gtk.main()

That’s it, pretty easy so far, if you run this file you will be greeted with our little GTK window that doesn’t do anything yet except quit properly when you close the window.

PyGame Window

The next step is to connect the button click event to a function. To do this we will need to use Glade again to edit our interface.

In the main window we need to select our button object and then in the properties Window select the “Signals” tab. There we will add a new signal by clicking on the signal browse button (…) and selecting “clicked”. This will create a handler called “on_btnHelloWorld_clicked” by default. We could change the name of this handler if we wanted but for now the default is good enough.

PyGame Window

That’s it for the work in Glade, now what we need to do is connect that event to something in our code. Fortunately this is pretty easily done using the gtk.glade.XML.signal_autoconnect function.

#Create our dictionay and connect it
dic = { "on_btnHelloWorld_clicked" : self.btnHelloWorld_clicked,
	"on_MainWindow_destroy" : gtk.main_quit }
self.wTree.signal_autoconnect(dic)

Basically the dictionary is created using the name of the event, and the function to connect it to. You can see that we connect our button’s click event with a new function, and that we connect the “on_MainWindow_destroy” event with the gtk.main_quit() function, this basically is a replacement for our earlier code that quit the program when the window is closed. Important: If you want to use that version of the dictionary you should go and add the destroy event to the main window in glade.

Note: Since this was missed by people I’ve added some images to make it more obvious what event to connect to:

PyGTK Window

Glade Window

The next thing to do is create our btnHelloWorld_clicked function to the HellowWorldGTK class:

def btnHelloWorld_clicked(self, widget):
	print "Hello World!"

Pretty simple! Now when we run it, and click on the “Click Me!” button we see “Hello World!” written our to the command line.

That’s it for this lesson, but so far I really like what I see working with PyGTK and Glade. Here is the full source:

#!/usr/bin/env python

import sys
try:
 	import pygtk
  	pygtk.require("2.0")
except:
  	pass
try:
	import gtk
  	import gtk.glade
except:
	sys.exit(1)

class HellowWorldGTK:
	"""This is an Hello World GTK application"""

	def __init__(self):
		
		#Set the Glade file
		self.gladefile = "pyhelloworld.glade"  
	        self.wTree = gtk.glade.XML(self.gladefile) 
		
		#Create our dictionay and connect it
		dic = { "on_btnHelloWorld_clicked" : self.btnHelloWorld_clicked,
			"on_MainWindow_destroy" : gtk.main_quit }
		self.wTree.signal_autoconnect(dic)

	def btnHelloWorld_clicked(self, widget):
		print "Hello World!"


if __name__ == "__main__":
	hwg = HellowWorldGTK()
	gtk.main()

Helpful links:

http://www.linuxjournal.com/article/6586
http://www.async.com.br/~kiko/pygtk-web/articles/bitpodder/BitPodder.htm
http://www.linuxjournal.com/article/7421
http://www.pygtk.org/articles.html
http://www.pygtk.org/tutorial.html

168 thoughts on “Creating a GUI using PyGTK and Glade”

  1. Thanks for the tutorial, it is a bit hard to read though(not really clear sections, can be annoying sometimes)

    Anyway, making my own application now with pygtk and glade, and I think it would be nice if you made clear that you need to modify other pieces of code that are plain pygtk.
    just like
    “hwg.hide()”
    doesn’t work normally here, but
    “hwg.wTree.get_widget(“MainWindow”).hide()”
    does. This is probably because of the parsing of glade to python.

  2. @Scott,

    in Glade-3, main window is by default invisible. To see it, you need to select main window, go to Common tab and select Visible -> Yes.

  3. when i run the following code.It shows the gui of treeview with only column name and nothing displayed content below it:-

    import pygtk
    pygtk.require(‘2.0′)
    import gtk
    import gobject

    class Window:
    def __init__(self):
    self.builder = gtk.Builder()
    self.builder.add_from_file(‘Tree.xml’)
    self.main_window = self.builder.get_object(“window”)

    #getting the treeview from the widget tree
    self.H2EView =self.builder.get_object(“treeview”)

    dic= {“on_window_destroy”:self.quit}
    self.builder.connect_signals(dic)

    # adding column to the treeview
    self.add_column_name(” Hindi “,0)
    self.add_column_name(” English “,1)

    #Creating ListStore model and linking with treeview Object
    self.H2EList = gtk.ListStore(str,str)
    self.H2EView.set_model(self.H2EList)

    # Adding elemrnts to the table
    self.H2EList.append([“manDua” , “Ragi”])

    self.main_window.show_all()

    def add_column_name (self,title,columnId):
    column = gtk.TreeViewColumn(title, gtk.CellRendererText() ,text=columnId)
    column.set_resizable(True)
    column.set_sort_column_id(columnId)
    self.H2EView.append_column(gtk.TreeViewColumn(title))

    def quit(self, widget):
    print “Window closed”
    gtk.main_quit()

    def main():
    app = Window()
    gtk.main()

    if __name__ == “__main__”:
    main()

    and the following is the Tree.xml



    – True False True – – True True automatic automatic – – True True

    kindly assist

  4. The Glade library is included in GTK now (called gtk.Builder), so the Glade library (Libglade) has been depreciated and is no longer needed. So, when you create a new project, choose “GtkBuilder” as your format rather than “Libglade”. And then you can remove all references and use of .glade in your code, with the result as follows:

    import sys
    try:
    import pygtk
    pygtk.require(“2.0″)
    except:
    pass
    try:
    import gtk
    except:
    sys.exit(1)

    class HelloWorldGTK:
    “””This is a Hello World GTK application”””

    def __init__(self):

    #Set the Glade file
    self.builder = gtk.Builder()
    self.builder.add_from_file(“pyhelloworld.glade”)

    #Get the Main Window, and connect the “destroy” event
    #self.window = self.wTree.get_widget(“MainWindow”)
    #if (self.window):
    # self.window.connect(“destroy”, gtk.main_quit)

    dic = {
    “on_btnHelloWorld_clicked” : self.btnHelloWorld_clicked,
    “on_MainWindow_destroy” : self.quit
    }

    self.builder.connect_signals( dic )

    def btnHelloWorld_clicked(self, widget):
    #print “Hello World!”
    #self.builder.get_object(“label1″)
    #lbl = “label1″
    #lbl.set_text(“Hello World!”)
    self.builder.get_object(“label1″).set_text(“Hello World!”)

    def quit(self, widget):
    sys.exit(0)

    if __name__ == “__main__”:
    HelloWorldGTK = HelloWorldGTK()
    gtk.main()

  5. Note that the above coce will not run if you cut and paste it because, unfortunately, this forum doesn’t seem to provide an option to insert code without it losing it’s indentations, which of course Python must have.

    I’m going try to use the code prefixes used on other forum comments to see if the indents are preserved:

    ::HLIGHT_BLOCK_1::

  6. Nope – “::HLIGHT_BLOCK_1::” doesn’t work. Can someone advise how to post code here?

  7. Very good tutorial. I followed the instructions step by step, the ran the python code. Nothing HAPPENED–the Hello World window did not appear…I am using Windows 7. Is that an issue? What code modifications are needed? See code below: I change sys to os–sys kept throwing up:

    Traceback (most recent call last):
    File “C:\…(path)
    sys.exit(1)
    SystemExit: 1

  8. Heya i am for the first time here. I came across this
    board and I in finding It truly helpful & it helped me out much.
    I am hoping to offer something back and help others
    like you aided me.

  9. Hey there, I think your blog might be having browser
    compatibility issues. When I look at your blog site in Firefox, it looks fine but when opening in
    Internet Explorer, it has some overlapping.
    I just wanted to give you a quick heads up! Other then that,
    very good blog!

  10. Hello, I have been struggling with using python and Glade to develop a few simple GUI based apps for my Ubuntu 12.04 based PC.
    It seems difficult to locate tutorial books and documentation to download and experiment with.

    Can anyone offer suggestions for a tutorial PDF that goes into the details of using the GTK+ imports. I get stumped when I try to figure out what the different attributes and methods that can be used with the imports associated with using Glade.

    I did take a look at Tkinter as it is included with the Python install (python 2.7.3) and as mentioned elsewhere, iy is not ‘pretty’.

    I have done some VB.NET on a XP PRO PC, so some of the concepts make sense and some do not.

    Without the ability to generate GUI programs the use of Python is somewhat limited.

    Most of the tutorials from the Glade website(s) seems to center on using C/C++ . I have a good amount of C experience , but that is using micro controllers , so not a big amount of help there. I really want to use Python for Linux (Ubuntu) work and not have to use C.

    Also, I really don’t want to have to use XML. From what I read, Glade takes care of that for you(?).

    So, I am hoping that I can get some good suggestions from here.

    I also don’t understand the difference from using PyGTK and/or Glade. Glade seems to offer the better of the worlds.

    Thanks for your postings and I will continue to keep digging.

    Best Regards to all.

  11. I have been looking for a decent example of using Glade. I will come back here again and take another look at it. I am currently using wxpython at the beginner level. I am just doing this stuff as a hobby. Glad may be easier to use, not sure.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>