Overclock.net banner

1 - 20 of 33 Posts

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #1
Writing a GUI app with Python & Glade

Edit: Please do check out the video screencast of this tutorial.

Here is what is to be created:



This tutorial will assume a basic knowledge of programming in general, and an understanding of Python. You don't even really need that, but if you don't know python well, you might need to look some stuff up, but google is your friend. This tutorial also assumes you are running Linux. I don't know about glade on Windows, so you'd have to check that out yourself.
You will also need to install python and glade.

Writing a GUI application to do a task may seem like a difficult job, but in fact, it can be very simple. Python is the language of choice for me, it's simple and fast to develop in, with a fair amount of power behind it.

First of all, we need an idea of what to do. Let's do something very basic to begin with, a program to add two numbers, and display an output. We'll start by creating a simple CLI app, which we'll convert.

tutCLI.py:

Code:

Code:
class adder:

result = 0

def __init__( self, number1, number2 ):
self.result = int( number1 ) + int( number2 )

def giveResult( self ):
return str(self.result)

endIt = False
while ( endIt == False ):
print "Please input two intergers you wish to add: "
number1 = raw_input( "Enter the first number: " )
number2 = raw_input( "Enter the second number: " )
try:
thistime = adder( number1, number2 )
except ValueError:
print "Sorry, one of your values was not a valid integer."
continue
print "Your result is: " + thistime.giveResult()
goagain = raw_input( "Do you want to eXit or go again? ('X' to eXit, anything else to continue): " )
if ( goagain == "x" or goagain == "X" ):
endIt = True
This is a simple python script to get the input. The class 'adder' does the actual addition. Taking two inputs in the constructor (__init__), and then adding the two, and storing the result in the 'result' member.
The rest is the stuff that makes our CLI work. It gives the user instructions, takes some input, then it adds the numbers (note this is in a try/except to see if an exception was thrown. This is so we don't throw ugly errors to the user if they input something which is not an integer. It then prints the result, and asks if the user wants to go again, all pretty self-explanetory.

Now we need to create a GUI for this. Open up glade.
Press the 'New Window' button on the left, under 'Toplevels'. This will give you an empty window.



Before we begin, I will make note that glade works in a way that web developers will be used to, by using relative positioning, and splitting the area to arrange things, not by absolute values.

You will need to create a vertical box with 3 items. This splits our window into three segments. The top will be instructions, the bottom buttons and information, the middle the entry areas.



Create a label, and put it up top, don't worry about the text at the moment. Next create a table 2 wide and 3 down in the middle, and finally a horizontal box with 2 items at the bottom.



In the middle, put a label in each as the three left-hand items, and a Text Entry as the right hand portion.



In the bottom, make another 2-item horizontal box in the bottom-left hand corner. Now add an image and a label to the this box. On the right of the main box add a two-item button box in the right hand slot. Add a button to each of these slots.



Add some appropriate text to the top label, and Number 1, Number 2, and Result to the labels on the left. This can all be done in the properties area on the right of your screen. Change your image in the bottom left hand corner to 'Stock' and then choose the stock image 'Warning'. Make the label next to it a warning (like "Sorry, one of your values was not a valid integer." in our CLI). For the two buttons, choose 'Stock' for both, and make one 'gtk-quit' and one 'gtk-add' - for obvious reasons.



OK, so we have everything set up, but it looks decidedly wonky and out of proportion. To counter this, you need to edit the way the items expand. Select the first Text Area, and go into 'packing'. Turn off the vertical 'Expand' option. Repeat this for all of the Text Areas and labels. You will need to go through your items forcing them to expand or not until it looks correct. (Only items in tables have individual horizontal and vertical expand options. For example, the button box should have 'expand' off.) Remember, you can use the tree view to the right to select items, so go through each one one-by-one and check it expanded and not, and see which works, you'll soon get the hang of what needs to be expanded to make the GUI function correctly.



You should end up with something like this:



Once you have, we still have a little to do in glade. Choose your Window (probably 'window1' in your treeview) and go to the 'General' tab in the properties window. Change the name to something more suitible - 'windowMain' is what I'll use. Set Window Title to something you want the user to see ("Latty's Amazing Adder!" in my case.). Next go to the signals tab, and open 'GtkObject' - and click on "destroy" - the dropdown menu under 'handler' - then choose 'on_windowMain_destroy' - This is the event that the GUI will give your application to say the user has tried to quite the application (by clicking on the close icon). Make sure to click somewhere else so it goes out of edit mode before doing anything else, otherwise it'll not save that signal.



Repeat this process for everything you will need to access, changing the names of the entries to something appropriate (these don't need any signals), changing the name of the bottom left hand hbox which contains your warning to something more apt, and changing the names of the two buttons then creating 'clicked' signals for both of them.

Almost there! Finally, we need to make a few small edits. Select the hbox which contains your warning (which should not be renamed something, hboxWarning in my case) - then set 'visible' to false. We don't want this warning shown to begin with. You need to do the opposite for the main window, which you do want visible, so make sure it is. You will also want to turn 'sensitive' on the result Text Entry (under 'Common') to be false - this is for the user to see the result, they don't need to edit it. This will 'grey-out' the box (allthough not in glade, for some reason. You also need to go to the button box containing your two buttons and set 'pack type' under 'packing' to end, so it doesn't move around when the warning appears and disappears.



There! Done with the GUI. Save it in the same folder as where you will develop your app. "main.glade" in my case.

OK, let's begin with our GUI script. First of all, we need to import the libraries we will need.

Code:

Code:
import sys
try:  
import pygtk  
pygtk.require("2.0")  
except:  
pass  
try:  
import gtk  
import gtk.glade  
except:  
print("GTK Not Availible")
sys.exit(1)
The sys library is there purely to allow us to call 'sys.exit' - used to exit the application. The rest is to import the GTK, our graphical library. It should all make sense.
Next we need to have our adder class again, this is unchanged from our original application (the wonders of object orientation, kids):

Code:

Code:
class adder:

result = 0

def __init__( self, number1, number2 ):
self.result = int( number1 ) + int( number2 )

def giveResult( self ):
return str(self.result)
Now, here comes the juicy bit, the GUI class.

Code:

Code:
class leeroyjenkins:

wTree = None

def __init__( self ):
self.wTree = gtk.glade.XML( "main.glade" )

dic = { 
"on_buttonQuit_clicked" : self.quit,
"on_buttonAdd_clicked" : self.add,
"on_windowMain_destroy" : self.quit,
}

self.wTree.signal_autoconnect( dic )

gtk.main()

def add(self, widget):
try:
thistime = adder( self.wTree.get_widget("entryNumber1").get_text(), self.wTree.get_widget("entryNumber2").get_text() )
except ValueError:
self.wTree.get_widget("hboxWarning").show()
self.wTree.get_widget("entryResult").set_text("ERROR")
return 0
self.wTree.get_widget("hboxWarning").hide()
self.wTree.get_widget("entryResult").set_text(thistime.giveResult())

def quit(self, widget):
sys.exit(0)
Basically, it loads the widget tree from your glade file, and then creates a list of signals and what methods they point to. In our case, closing the window and clicking quit both make it quit (a member function which is pretty obvious), and clicking add calls our add member function.

The gtk.main() function just makes a loop which will display the GUI, and handle any signals as you have told it to.

Notice members called by signals need a 'widget' parameter. This is the widget that set off that signal. We don't need this, but you might in another case. Our add function should look very familiar, and should be pretty self explanetory.

Alright, that's it! Here is the end result in full:

Code:

Code:
import sys
try:  
import pygtk  
pygtk.require("2.0")  
except:  
pass  
try:  
import gtk  
import gtk.glade  
except:  
print("GTK Not Availible")
sys.exit(1)

class adder:

result = 0

def __init__( self, number1, number2 ):
self.result = int( number1 ) + int( number2 )

def giveResult( self ):
return str(self.result)

class leeroyjenkins:

wTree = None

def __init__( self ):
self.wTree = gtk.glade.XML( "main.glade" )

dic = { 
"on_buttonQuit_clicked" : self.quit,
"on_buttonAdd_clicked" : self.add,
"on_windowMain_destroy" : self.quit,
}

self.wTree.signal_autoconnect( dic )

gtk.main()

def add(self, widget):
try:
thistime = adder( self.wTree.get_widget("entryNumber1").get_text(), self.wTree.get_widget("entryNumber2").get_text() )
except ValueError:
self.wTree.get_widget("hboxWarning").show()
self.wTree.get_widget("entryResult").set_text("ERROR")
return 0
self.wTree.get_widget("hboxWarning").hide()
self.wTree.get_widget("entryResult").set_text(thistime.giveResult())

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

letsdothis = leeroyjenkins()
Note the last line which creates an object of our GUI class, this makes the program actually begin.




There we have it, a simple GUI app with Python and Glade. It's not that hard to do. This example, of course, may seem like a lot of work for little result, as the resulting application is not that useful, but what you have learnt here can easily be applied to other things.

If you want to see a fully functional app written in python/glade, check out simpleconf. This was written for OCNix and is made in exactly the same way as is outlined here. You should be able to see how it functions. The source code is right there, so take a look.

Edit: Forgot to mention, there is a reason to use the stock buttons wherever possible. They are automatically translated to the language the user is currently using, and change icon with the theme the user is using, so it always fits in.

Attached is the full source to everything.
 

·
Registered
Joined
·
6,614 Posts
Looks like a sweet guide Latty! When I've got some time i'll give it a proper read, It might even make me learn how to code in Python


Can't believe it's been here 3 weeks and this is the first comment.

Nice job rep+ and 5 stars
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #3
Cheers. I just presumed there were not that many people interested in Linux and Programming here, by the looks of it. Glad to know it's going to use
 

·
Registered
Joined
·
2,363 Posts
latty you should help me with learning python i got some question i cant get anyone to anwser!
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #6
Because a) The GTK & Python are cross-platform, b) VB is a proprietry format controlled by M$, c) Python is a much nicer language, with more power.

What makes it awesome? Try writing in it.
 

·
Registered
Joined
·
309 Posts
Last I checked, VB (under Mono) can't open and use a Glade file. But maybe my understanding of GTK# is lacking.
 

·
Registered
Joined
·
988 Posts
Thanks for that!

I learnt 68000 assembly back in the early 90`s not long out of school were ya learnt BASIC in `Computer Studies` on crusty old BBC micros! (they had econet which was cool!)

what seems to go for `Computer Studies` these days??? (in the UK BTW!!)

MS Office, Internet explorer and Fakebook.....

Why do they not teach something that could get them interested in programing and become the next generation of arse kicking game creators???
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #11
Too true. ICT is a course in being a receptionist. It's a joke.

This thread had been here for ages, then it suddenly gets active out of nowhere XD
 

·
Premium Member
Joined
·
15,202 Posts
Quote:

Originally Posted by DarkNite View Post
integer not interger
You know it took me a month after i first started to notice that.

Hey Latty, might want to ask BFRD about getting this stickied.
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #13
You think it's sticky-worthy?
 

·
Registered
Joined
·
1 Posts
I was looking for a good tutorial for pygtk and glade and yours fited perfectly.
Hope I can have some better interfaces for python programs!

Thanks a lot
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #16
Quote:

Originally Posted by paulopastore View Post
I was looking for a good tutorial for pygtk and glade and yours fited perfectly.
Hope I can have some better interfaces for python programs!

Thanks a lot
Glad I could help.
That said, this guide is getting a bit old, and Glade is being replaced with gtk.Builder - this removes the need for an extra library, and will have more features.
That said, gtk.Builder needs a very new version of the GTK, so it's still not mainstream, so this is not something you should worry about right now.
gtk.Builder is also largely very similar to glade. Glade will still exist as a GUI to create gtk.Builder files, and you can convert pretty easily. Changing the code should again be pretty simple.
 

·
Registered
Joined
·
1 Posts
Hello!! I'm trying to learn how to build my GUIs from your tutorial (very good, thanks). I went over all of it. After finished, I run the Python file of the GUI "tutgui.py" and got:

GTK Not Availible
>>>
>>> import gtk
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\\Python25\\Lib\\site-packages\\gtk-2.0\\gtk\\__init__.py", line 48, in <module>
ImportError: DLL load failed: The specified procedure could not be found.
>>>

I use Python 2.5 on Win32 xp platform, I know you use different OS. What you think I need to do/install/reinstall/add to the code/take off code... to correct this issue? If it is not matter of my system and I should specify something else in your code for it to run on my Win32?, where if so? should I use Pygtk somewhere in the codes?

Please heeeeeeelp!
Thanks so much,
Angelica.
 

·
Premium Member
Joined
·
4,447 Posts
Discussion Starter #19
Quote:

Originally Posted by maegregory View Post
Hello!! I'm trying to learn how to build my GUIs from your tutorial (very good, thanks). I went over all of it. After finished, I run the Python file of the GUI "tutgui.py" and got:

GTK Not Availible
>>>
>>> import gtk
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\\Python25\\Lib\\site-packages\\gtk-2.0\\gtk\\__init__.py", line 48, in <module>
ImportError: DLL load failed: The specified procedure could not be found.
>>>

I use Python 2.5 on Win32 xp platform, I know you use different OS. What you think I need to do/install/reinstall/add to the code/take off code... to correct this issue? If it is not matter of my system and I should specify something else in your code for it to run on my Win32?, where if so? should I use Pygtk somewhere in the codes?

Please heeeeeeelp!
Thanks so much,
Angelica.

Quote:

Originally Posted by rabidgnome229 View Post
I'm guessing you need to install GTK for windows
Indeed, you need to install the GTK and pyGTK.
 

·
Registered
Joined
·
1 Posts
Hi Lattyware et al

I know this is an old thread, but it was one of the first that I came across when searching for help, and probably the best getting-started walkthrough for Glade and python. Anyway, you mention that gtk.Builder is replacing libglade, so I thought I would follow that route (starting to learn a bit of python), and after much huffing and puffing have got your adder program to work with gtkbuilder.

Here's the code that works for me if anyone's interested:

Code:

Code:
import sys
try:  
    import pygtk  
    pygtk.require("2.0")  
except:  
    pass  
try:  
    import gtk  
except:  
    print("GTK Not Availible")
    sys.exit(1)

class adder:

    result = 0

    def __init__( self, number1, number2 ):
        self.result = int( number1 ) + int( number2 )

    def giveResult( self ):
        return str(self.result)

class adderGui:

    wTree = gtk.Builder()

    def __init__( self ):
        self.builder = gtk.Builder()
        self.builder.add_from_file("Adder.glade")
        self.window = self.builder.get_object ("windowMain")
        if self.window:
            self.window.connect("destroy", gtk.main_quit)
        self.entry1 = self.builder.get_object ("entry1")
        self.entry2 = self.builder.get_object ("entry2")

        dic = { 
            "on_buttonQuit_clicked" : self.quit,
            "on_buttonAdd_clicked" : self.add,
            "on_windowMain_destroy" : self.quit,
        }

        self.builder.connect_signals( dic )

    def add(self, widget):
        entry1 = self.builder.get_object ("entry1")
        entry2 = self.builder.get_object ("entry2")
        try:
            thistime = adder( entry1.get_text(), entry2.get_text() )
        except ValueError:
            self.builder.get_object("hboxWarning").show()
            self.builder.get_object("image1").show()
            self.builder.get_object("entryResult").set_text("ERROR")
            return 0
        self.builder.get_object("hboxWarning").hide()
        self.builder.get_object("image1").hide()
        self.builder.get_object("entryResult").set_text(thistime.giveResult())

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

adderGui = adderGui()
adderGui.window.show()
gtk.main()
I daresay that it could be tidier or bettered in many ways (pointers welcome). Any suggestions as to where to go next?

Cheers
Charlie
 
1 - 20 of 33 Posts
Top