Chapter 2. Goodbye World

To begin our introduction to Gtk-Perl, we'll start with one of the simplest programs possible. This program will create a small window with one button labelled "Goodbye World". Clicking on the button or closing the window will exit the program.

Goodbye World Source

      
#!/usr/bin/perl -w

use Gtk;         # load the Gtk-Perl module
use strict;      # a good idea for all non-trivial Perl scripts

set_locale Gtk;  # internationalize
init Gtk;        # initialize Gtk-Perl

# convenience variables for true and false
my $false = 0;
my $true = 1;

# widget creation
my $window = new Gtk::Window( "toplevel" );
my $button = new Gtk::Button( "Goodbye World" );

# callback registration
$window->signal_connect( "delete_event", \&CloseAppWindow );   
$button->signal_connect( "clicked", \&CloseAppWindow );

# show button
$button->show();

# set window attributes and show it
$window->border_width( 15 );
$window->add( $button );
$window->show();

# Gtk event loop
main Gtk;

# Should never get here
exit( 0 );



### Callback function to close the window
sub CloseAppWindow
{
   Gtk->exit( 0 );
   return $false;
}


# END EXAMPLE PROGRAM
      
   

On Unix, you will need to make the above program executable by using the following command:

chmod a+x goodbyeworld

If you still have a problem running it, you should make sure that the path to perl on the first line is correct and that Gtk-Perl was properly installed (try running the test programs that come with Gtk-Perl if you're not sure of this).

When you run the above program, you should see something similar to this:

Goodbye World Screenshot

Your program may not look exactly like the picture above. GTK is, among many things, themable. This means that the user gets to decide how widgets look, what colors and pixmaps should be used, what fonts to use, and so on. The above snapshot was using the default theme. Furthermore, the title bar may look different depending on what your preferred window manager or Operating System is.

2.1. Stepping through Goodbye World

Now, lets see if we can't step through the above program and make some sense of it.

use Gtk; needs to be included for all Gtk-Perl programs. This allows Perl to use the variables, functions, structures, etc. that are defined by GTK. This can be easily mixed with other use directives such as use strict;.

init Gtk; also needs to be included for all Gtk-Perl applications. This initializes the GTK module and sets up a few things for us such as the default visual and color map, initializes the library for use, and the default signal handlers.

set_locale Gtk; should be included if you want your program to be friendly to people who use a language other than English. This simple step allows widgets such as the text entry widget to accept input from a non-ascii character set. More needs to be done to make a program truly "internationalized", but that is beyond the scope of this document.

The $true and $false variables are something I use to tell the difference between a boolean value and a numeric value. You don't have to do this, but I choose to do it in order to keep from confusing beginners. Without this, you would have to decide if that "1" is just there to represent truth, or if it has some other meaning. What happens if you change it to "2"? I will use $true and $false in all of my programs so that you won't have to ask this kind of question when looking at my sample code.

new Gtk::Window() creates a new window. The Window Manager decides how to decorate it (with things like the title bar) and where to place it. All GUI widgets are placed inside a window, and you can have more than one window per program. The argument tells X what kind of window it is. Top-level windows have no parent window, and are not contained within any windows. You can also create dialog windows, using new Gtk::Dialog().

new Gtk::Button() creates a new button. In this case, we created one with a text label. What would have happened if we didn't specify the text to put on the button? Try it and see what happens for yourself. Notice the size of the button and the window when you do this. GTK will automatically resize widgets unless you tell it not to (this includes the window). For this reason it is okay to not worry about what font size or style the user might have defaulted to. You just tell GTK how to do the layout, and let it do the rest. For more information on buttons, see the chapter on buttons .

The border_width() function will take a container (such as a window) and put some space around it. This keeps your application from looking cluttered. The number that was sent as an argument is the width (in pixels) of the border created. Try experimenting with different values.

signal_connect() connects an event or signal with a subroutine call. An example would be the click of a mouse button. In laymans terms, when an event or signal is generated GTK looks to see if that event has a subroutine registered for that widget and that event, and if so, it executes that subroutine. If there is no registered subroutine registered, then nothing happens. Registered subroutines are called callbacks. Much more information on signals and events (including a description of what the difference between them is) is available in the chapter on Signals and Events .

In our example, the first argument to signal_connect() is a string holding the name of the event you wish to register and the second argument is a reference to the subroutine to be called when the event occurs. Other events may require different arguments to signal_connect().

The add() function will take a widget, and add it to a container (in this case the window). If we didn't do this, we wouldn't see the button because it wouldn't be inside the window.

The show() function makes a widget visible. Don't run show() until all the properties of a widget have been set. You should always show child widgets before parent widgets (in this example, show the button before the window it is contained in). This way the window appears all at once, making the program appear more professional and a little faster (even though it really isn't).

main Gtk; enters the GTK main event processing loop. This is another line that you will see in every Gtk-Perl application. When control reaches this point, GTK will sleep waiting for X events (such as button or key presses), timeouts, or file IO notifications to occur. Think of this as an infinite loop that is broken out of with the Gtk->exit() call. On the very next line I put an exit statement, which should never be executed, but I put one there just in case.

The subroutine at the bottom is the one that is called when the button is clicked or when the window is closed. The only interesting thing here is the Gtk->exit() call, which will exit the program using the argument as the exit code. The return statement is very important for a subroutine executed when the 'delete_event' is called. A false value means "go ahead and kill the window", while a true value means "do not kill the window". This is useful for asking "are you sure" questions before the window is blown away.