Lines 7-69 define the HelloWorld class that contains all the callbacks as object methods and the object instance initialization method. Let's examine the callback methods.
Lines 11-12 define the hello()
callback method that will be called when the button is "clicked". When
called the method, prints "Hello World" to the console. We ignore the object
instance, the widget and the data parameters in this example, but most
callbacks use them. The data is defined with a default value of None because
PyGTK will not pass a data value if it is not included in the connect()
call; this would trigger an error since the callback is expecting three
parameters and may receive only two. Defining a default value of None allows
the callback to be called with two or three parameters without error. In
this case the data parameter could have been left out since the hello()
method will always be called with just two parameters (never called with
user data). The next example will use the data argument to tell us which
button was pressed.
def hello(self, widget, data=None): print "Hello World"
The next callback (lines 14-24) is a bit special. The "delete_event" occurs when the window manager sends this event to the application. We have a choice here as to what to do about these events. We can ignore them, make some sort of response, or simply quit the application.
The value you return in this callback
lets GTK know what action to take. By returning TRUE, we let it know that
we don't want to have the "destroy" signal emitted, keeping our application
running. By returning FALSE, we ask that "destroy" be emitted, which in
turn will call our "destroy" signal handler. NOTE: the comments have been
removed for clarity.
def delete_event(widget, event, data=None): print "delete event occurred" return gtk.TRUE
callback method (lines 27-28) causes the program to quit by calling gtk.mainquit().
This function tells GTK that it is to exit from gtk.mainloop()
when control is returned to it.
def destroy(widget, data=None): gtk.mainquit()
Lines 30-69 define the HelloWorld object instance initialization method __init__() that creates the window and widgets used by the program.
Line 32 creates a new window, but it is
not displayed until we direct GTK to show the window near the end of our
program. The window reference is saved in an object instance attribute
(self.window) for later access. In this example, there is no later access
required so saving a reference to the window in the object instance is
not required. Later examples will not save references if not required.
self.window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
Lines 39 and 44 illustrate two examples
of connecting a signal handler to an object, in this case, the window.
Here, the "delete_event" and "destroy" signals are caught. The first is
emitted when we use the window manager to kill the window, or when we use
the GtkWidget destroy() method
call passing in the window widget as the object to destroy. The second
is emitted when, in the "delete_event" handler, we return FALSE.
self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy)
Line 47 sets an attribute of a container
object (in this case the window) to have a blank area along the inside
of it 10 pixels wide where no widgets will be placed. There are other similar
functions which we will look at in the section on
Line 50 creates a new button and saves
a reference to it in self.button.
The button will have the label "Hello World" when displayed.
self.button = GtkButton("Hello World")
In line 55 we attach a signal handler
to the button so when it emits the "clicked" signal, our hello()
callback method is called. We are not passing any data to hello()
so we just pass None as the
data. Obviously, the "clicked" signal is emitted when we click the button
with our mouse pointer. The user data parameter value None is not required
and could be removed. The callback would then be called with one less parameter.
self.button.connect("clicked", hello, None)
We are also going to use this button to
exit our program. Line 60 illustrates how the "destroy" signal may come
from either the window manager, or from our program. When the button is
"clicked", same as above, it calls the hello()
callback first, and then the following one in the order they are set up.
You may have as many callbacks as you need, and all will be executed in
the order you connected them. Since the self.window.destroy()
callback is a GtkWindow method that accepts only a GtkWidget as an argument,
we use the connect_object()
method here instead of straight connect().
When the self.window.destroy()
method is called it will cause the "destroy" signal to be emitted from
the window which will in turn cause the HelloWorld destroy()
method to be called to end the program.
self.button.connect_object("clicked", self.window.destroy, self.window)
Line 63 is a packing call, which will
be explained in depth later on in
Widgets. But it is fairly easy to understand. It simply tells GTK that
the button is to be placed in the window where it will be displayed. Note
that a GTK container can only contain one widget. There are other widgets,
that are described later, which are designed to layout multiple widgets
in various ways.
Now we have everything set up the way
we want it to be. With all the signal handlers in place, and the button
placed in the window where it should be, we ask GTK (lines 66 and 69) to
"show" the widgets on the screen. The window widget is shown last so the
whole window will pop up at once rather than seeing the window pop up,
and then the button form inside of it. Although with such a simple example,
you'd never notice.
Lines 71-74 define the main()
function which calls the gtk.mainloop()
function to wait for events to come from the X server and calls on the
widgets to emit signals when these events come.
def main(): gtk.mainloop()
Lines 78-80 allow the program to run automatically
if called directly or as an argument of the python interpreter. Line 79
creates and instance of the HelloWorld class and saves a reference to it
in the hello variable. Line
80 calls the main() function
to start the GTK event processing loop.
if __name__ == "__main__": hello = HelloWorld() main()
Now, when we click the mouse button on a GTK button, the widget emits a "clicked" signal. In order for us to use this information, our program sets up a signal handler to catch that signal, which dispatches the function of our choice. In our example, when the button we created is "clicked", the hello() function is called with a None argument, and then the next handler for this signal is called. The next handler calls the window destroy() function, passing it the window widget as its argument, destroying the window widget. This causes the window to emit the "destroy" signal, which is caught, and calls our HelloWorld destroy() callback function, which simply exits GTK.
Another course of events is to use the window manager to kill the window, which will cause the "delete_event" to be emitted. This will call our "delete_event" handler. If we return TRUE here, the window will be left as is and nothing will happen. Returning FALSE will cause GTK to emit the "destroy" signal which of course calls the HelloWorld "destroy" callback, exiting GTK.