Chapter 2. The trivial "Hello Gtk2-Perl "

Problem

Curiosity has overwhelmed you, and you want to see Gtk2-Perl in action.

2.1. Solution

Start off by the typical 'Hello' program. Open your favorite editor and enter the following code in a file.

	
 1 #! /usr/bin/perl -w
 2 use strict;
 3 use Gtk2 -init;
 4 my $window = Gtk2::Window->new ('toplevel');
 5 $window->signal_connect (delete_event => sub { Gtk2->main_quit });
 6 
 7 	my $button = Gtk2::Button->new ('Action');
 8 	$button->signal_connect (clicked => sub { 
 9 	
10   		print("Hello Gtk2-Perl\n");
11 		
12   	});
13 	
14 $window->add ($button);
15 $window->show_all;
16 Gtk2->main;

  1. Save it

  2. Make it executable:

    			# chmod 755 (script name)
    			

  3. Execute it:

    			# ./(script name)
    			

2.1.1. Screenshot

Figure 2-1. Hello Gtk2-Perl

2.1.2. Discussion

This is a very basic program used for introduction purposes.

  • #! /usr/bin/perl -w
    This is a line that any executable perl program will start with. We call it the "she-bang" line.(#- she, !- bang). This is followed by the path where the perl executable can be found on your system. Please check it, by executing the following command:
    	# which perl
    The reply should then be appended to the '#!' part. The '-w' is a directive to the Perl interpreter, telling it to enable useful warnings.

  • use strict; 
    This is another directive to the Perl interpreter that forces good programming practice like variable declaration.

  • use Gtk2 -init;
    Just about every Gtk2-Perl script, which is not a module, should contain "use Gtk2 -init". This initialization should take place before using any other Gtk2 functions in your GUI applications. It will initialize everything needed to operate the toolkit and parse some standard command line options. [1]

  • To show things on the screen, it is necessary to create a window. We create a window by:

    my $window = Gtk2::Window ->new ('toplevel');
    The new method accepts as an argument the type of window to be created. Creating a window (or any other widget) does not show it on screen. To show it on the screen, you have to call the Gtk2::Widget's show method.

    Tip

    You can call the show_all() method on a widget, to show that widget, and all its child widgets.

  • $window->signal_connect (delete_event => sub { Gtk2 ->main_quit });
    This connects the delete_event signal to an anonymous sub-procedure, which calls the Gtk2->main_quit method. The delete_event is emitted when the user closes the window.

  • my $button = Gtk2::Button ->new ('Action);
    This creates a new object called $button from the Gtk2::Button class. It also will create a label called 'Action' on the button.

  • $button->signal_connect (clicked => sub { 
      	print("Hello Gtk2-Perl\n");
      	});
    	
    This connects the clicked signal to an anonymous sub-procedure, which prints "Hello Gtk2-Perl ".

  • $window->add ($button);
    $window is a subclass of Gtk2::Container. You add a widget to a container using the add method. Adding more than one widget to a container is not trivial. The reason for this is that Gtk+ has not been designed to set widgets at a specific location in their parent widget. (This is not completely true [2]) Instead, Gtk+ asks that you pack your widgets in their parent widget. This means that if the parent widget gets resized, it's child widgets are resized as well, depending on the packing options that were set. One of the reasons that the Gtk+ library was set up this way, is that the size of a widget is not well-defined. This means that a button's size depends on whether it is the default widget of the window or not. Given that this is so, the placement of such a button is not well-defined either.

    The most common ways of packing widgets in a parent widget are the following:

    1. using a vertical box

    2. using a horizontal box

    3. using a table

    This will be discussed more in depth later.

  • $window->show_all;
    Make all widgets inside $window visible by calling this method. In this case it is only $button.

  • Gtk2->main;
    This enters the main loop, which will cause the program to wait for user input via the mouse or keyboard. Later in the book we'll also use other means of input, IE network sockets or feedback from a database.

Notes

[1]

More on use Gtk2 -init

When we write a GUI program, we need a graphical environment for it to live in. This will be X on Linux, and Windows on Windows. To ensure that there is such an environment for our program to show itself in, Gtk+ needs to be initialized first. Gtk+ will then attempt to connect to the display.

Should there not be a display available, we may still want continue with the program, BUT resort to another type of interface. (Typically this will be a "cursors" interface, like many of the setup programs available in Linux does.)

In such a scenario, we should not call Gtk2->init(). Since Gtk2-Perl is a binding to underlying C code, this will call the gtk_init() C function. When this function cannot connect to the display, it aborts the program, bypassing all of Perl's exception mechanisms.

When we want a fall back mechanism we use Gtk2->init_check(). This will allow us to continue with the program, in the absence of a graphical environment. Now we can use the second choice interface.

Since Gtk2->init() is the common case, the Gtk2 module allows '-init' as an import argument to mean "go ahead and call Gtk2->init() for me".

Good programming practice

To reuse code, we write library modules in Perl (that is a .pm file). We can create our own modules and make use of Gtk2-Perl. To make our modules programmer friendly, we should NEVER use init in them. Not using init in the module, will allow the script that uses our module to continue, and use alternatives when there is no graphical environment available.

Tip

Only script files using Gtk2-Perl should call Gtk2->init() or use the -init import argument. NEVER library modules.

[2]

Gtk2::Fixed allows you to do fixed layouts, but the reader is strongly advised against the use of Gtk2::Fixed.