Now, whenever you click GO! the results are displayed in your window.
By dividing your main window with a set of vertical panes, you can
resize this window, if you like (Figure 9).

Figure 9. Clicking GO! loads the Web page and displays it in the
TextView.

TreeViews and Lists

Unlike GTK v1, under GTK v2 a tree and a list basically are the same thing;
the difference is the kind of store each of them uses.
Another important concept is the TreeIter, which is a
datatype used to store a pointer to a particular row in a tree or list. It
doesn't offer any useful methods itself, that is, you can't ++
it to step through the rows of a tree or list. However, it is passed into
the TreeView methods whenever you want to reference a particular location
in the tree. So, for example:

The screenshot in Figure 10 shows the results. I've replaced
the TextView with a TreeView, as you can see.

Figure 10. An Example TreeView with Two Columns

A list is done the same way, except you use ListStore instead
of TreeStore. Also, most likely you will use ListStore.append() instead of
insert_after().

Using Dialogs

A dialog differs from a normal window in one important
way—it returns a value. To create a dialog box, click on the
dialog box button and name it. Then, in your code,
render it with
[3]gtk.glade.XML(gladefile,dialogboxname). Then call
get_widget(dialogboxname) to get a handle to that particular widget
and call its run() method. If the result is gtk.RESPONSE_OK, the
user clicked OK. If not, the user closed the window or clicked Cancel.
Either way, you can destroy() the widget to make it disappear.

One catch when using dialog boxes: if an exception happens
before you call destroy() on the widget, the now unresponsive dialog box
may hang around, confusing your users. Call widget.destroy() right after
you receive the response and all the data you need from any entry boxes in
the widget.

Using input_add() and gtk.mainiteration() to Handle Sockets

Some day, you probably will write a pyGTK application
that uses sockets. When doing so, be aware that while your
events are being handled, the application isn't doing anything
else. When waiting on a socket.accept(), for example, you are going
to be stuck looking at an unresponsive application. Instead,
use gtk.input_add() to add any sockets that may have read events to
GTK's internal list. This allows you to specify a callback to
handle whatever data comes in over the sockets.

One catch when doing this is you often want to update your
windows during your event, necessitating a call to
gtk.mainiteration(). But if you call gtk.mainiteration() while within
gtk.mainiteration(), the application freezes. My solution for
CANVAS was to wrap any calls to gtk.mainiteration() within a check to
make sure I wasn't recursing. I check for pending events, like
a socket accept(), any time I write a log message. My log function
ends up looking like this:

def log(self,message,color):
"""
logs a message to the log window
right now it just ignores the color
argument
"""
message=message+"\n"
self.logwindow.insert_at_cursor(message,
len(message))
self.handlerdepth+=1
if self.handlerdepth==1 and \
gtk.events_pending():
gtk.mainiteration()
self.handlerdepth-=1
return

It seems with glade-3 visibility of GtkWindow is off by default. That means, if you do the steps outlined here and run the program you exactly see nothing. To turn visibility on, select the GtkWindow (serverinfo) in the tree view in glade, select the Common tab, and set Visible to Yes. Trivial, yes, but took me some time to find in this property zoo.

I am recently working with python. I want to create a GUI where i want to appear one window after clicking on the button of another window. How can I do that?
And after calling one window I want the control should be gone to next window and it shouldn't remain on initial one.
Plz can anybody help me?

I am recently working with python. I want to create a GUI where i want to appear one window after clicking on the button of another window. How can I do that?
And after calling one window I want the control should be gone to next window and it shouldn't remain on initial one.
Plz can anybody help me?

I'm having just a couple problems though.
-How do you add keyboard shortcuts?
-Whenever I run the program from a different directory (i.e. "../file.py") it can't find the Glade file and dies. How do you tell Python to look in the same directory the .py file is in?

The same thing happens when I replace the initialization of logwindowview with self.logwindowview=gtk.glade.XML(gladefile,"textview1"), except instead of "Nonetype object" I get "gtk.glade.XML object" in the error. Am I missing something?

I don't know for sure, but just a guess there's probably not a very big difference since all the drawing and socket handling is still in C somewhere under all the Python code; I wouldn't imagine this particular app to be very different from it's C counterpart.

The text confuses vertical and horizontal boxes. This is probably obvious, but I don't want anyone to be confused when the text says horizontal box when referring to figure 2, when it is in fact a vertical box. The text for figure 3 says vertical box but should say horizontal box.

I was just discovering pyGtk and marvelous pyGlade, this quite complete and simple introduction comes at the right time ! (I just found a pyGlade tutorial which was too simple and written for glade1, and pyGtk faq is quite chaotic (that's also fun))
I like the eleguance of such a solution.
I would be interested in knowing how to pack a python application in a win32 installer.
thanks.
Alex

Greate article, I was just about to start writing a ton of threading code since I had never heard of input_add(), thanks for saving me the trouble.

I think the time for Python based GTK2 apps is now. Two, or even one, year ago I wouldn't have chosen Python for my project because the dependencies were too many. But since Red Hat now codes all their configuration utilities with pyGTK2 I am confident that many will already have all the libraries installed and that the language bindings will continue to be maintained. If distributed properly there is no difference between a GTK app done in C or python from the end users point of view, as it should be.

I'm getting an error when running.
First I think the following line should have been commented out.
(self.button1_clicked, arg1,arg2) , ...
Second I'm getting an the following error.
File "./serverinfo.py", line 47
self.wTree.signal_autoconnect (dic)
^
SyntaxError: invalid syntax

Any Ideas, at first I typed everything in. Thinking there must have been a typo somewhere, I copied and pasted from the site and still get that error.

Another option is to get the .tgz file from the ftp site mentioned at the end.
The code in the article (both online and in print) has been through some
sort of formatter which seems to not like Python..

So how involved is it to roll out python, pygtk, gtk2 and your application for clients who use windows and have none of that installed? Is it a case of it being better for you to do it yourself or is there a neat automated way one could create an "installer"? I was going to use python + pygame for a recent project, but ended up doing it in C for ease of distribution (windows ppl just download a binary and run it).

Personally, I make my clients "Do it themselves". This currently involves downloading three executables from public websites, and double-clicking on each of them in turn.

In other words, it is extremely easy. It does take a few megs, but we've all got a few megs to spare for Python, right?

There is an annoying gotcha or two with Win32, of course. My current favorite is that Win32 will let you listen on one port twice in a row. Aside from that minor issue though, the Win32 CANVAS (which is what the article is based on) runs exactly the same as the Linux CANVAS. This was an impotant design consideration for me when I started the project.

"just for next time". Pygame games are easily turned into standalone binaries. If you use one of the free "installer" programs, no one will ever know it was written in python. There are already "shareware" style games written in python for windows users. examples? click and play!

If you're considering writing an app. for GTK+ 1.2, keep in mind that the Python bindings for GTK+ 2 are actively maintained. If you encounter a bug in the old bindings, of which I'm sure there are a few, they will not likely be fixed.

A cool feature of the latest PyGTK release, 1.99.17, is support for custom widgets. GLADE's widget palette isn't complete, so you can add a placeholder with the name of a widget creation function. I use this to embed gnome-terminal's VTE terminal emulator widget.

You'll notice that GLADE's signal handler drop-down list contains the names of C functions, like gtk_widget_show(). You can take advantage of this by writing Python functions with the same name. I frequently use the following functions:

gtk_main_quit

gtk_true

gtk_widget_hide

gtk_widget_hide_on_delete

gtk_widget_show

gtk_window_present

Define these before the call to signal_autoconnect() function and you can pass it the value of the built-in locals() function. No need to write your own mapping dictionary.

PyGTK is good stuff. If you've ever seen a GTK+ program written in C, you'll appreciate how elegant a comparable Python can be.

"A cool feature of the latest PyGTK release, 1.99.17, is support for custom widgets. GLADE's widget palette isn't complete, so you can add a placeholder with the name of a widget creation function. I use this to embed gnome-terminal's VTE terminal emulator widget."

I have tried finding system documentation as well as googled for implementations of python-vte and the use of vte_terminal_new() but there are no examples at the time of writing.

Please elaborate with a brief example of how to embed a terminal in a GTK window.

One clarification regarding signal_autoconnect(): if you write straight-line procedural code, as you are likely to do when starting out, you can define your handler functions at the top level and pass locals() to signal_connect(). For example:

def on_button1_clicked( button, *args ):

...

gtk.glade.XML( 'project1.glade' ).signal_autoconnect( locals() )

If your handlers are in a class, as in this article, you can pass self to signal_autoconnect(). For example: