Here's a little tutorial/review/something that I put together one day after discovering Glade. It's a wonderful program and I thought that with a clear description of how to get going with it, more people would use it, and beautiful user interfaces would abound. I hope this is good enough to go into the tutorials section, after some editing and correcting.

Going GUI over Glade

A bit of background

I had pretty much despaired of ever doing beautiful graphics in Perl. To be completely frank, I had even started learning Java in the hope that I could do a front end in Java and somehow have it reporting back to a Perl program that would do all the work. Then one day when I was poking through my distribution, I found a design tool called Glade, and installed it, just for the hell of it.

I was mucking about, enjoying the user interface and the spanky look when I stumbled accross the option "export as Perl". Oook!

Perl is right up there on the graphics front, and has style. I recently bagged out the Gtk-Perl distribution because the documentation was, well, non-existant. I figured Tk would win, because it's got buckets of docs. But now that there is a stable design environment for Gtk, I'm switching. Although the Gtk tutorial has improved the documentation still bites.

What is Gtk?

Gtk is the Gimp Tool Kit - a suite of libraries that does graphics stuff. It has some snazzy features, like themes, animated buttons and heaps of useful widgets. In general you don't have to worry about it. It just sits there, hidden away, doing it's stuff. It's the code that actually draws and animates buttons, text boxes, list boxes and the rest.

What is Gtk-Perl?

Gtk-Perl is some modules that use Gtk to do windowing stuff in Perl. They rightly have the reputation for being hard to use and poorly documented (I couldn't find anything approaching a reasonable doco, and I did look. Links anyone?). At the moment Gtk-Perl is only available for Linux.

What is Glade?

Glade is a design program that lets you layout buttons, windows, menus, frames and other graphical widgets to design a good looking interface to your Perl program. Then you press the build button and it spits out a some modules that do all the Gtk-Perl stuff for you. The modules it spits out are full of POD and useful comments like "subroutines go here", as well as some handy subroutines, like one to pop up an 'About this program' box. It even builds a program to launch your interface. You literally type perl and up springs your window.

Working with Glade

If you have ever had the dubious pleasure of working with MS Visual Basic, then you will be right at home with Glade. The author even refers to windows as 'forms', which is the clever Microsoft word for "windows". For those who haven't done the VB thing, below is a simple little tutorial for creating a window with some stuff in it. It is easy, but there are still some tricks.

Good layout systems these days do not just "put the button here, put the text box there". If you work like that, the objects don't move when someone resizes your window, and your buttons and whatnot will stay clustered in the top left corner like frightened sheep.

You want to have certain objects like the text boxes get bigger and smaller as the rest of the window changes size. But you don't want the buttons to change size, because that would look silly, and make your users sea sick.

At same time, if someone uses the theme to change the size of the fonts, you want the buttons and text objects to get bigger or smaller to hold the new font properly... what to do?

Leave it all to the packer. Take a deep breath and hand over some more control to the software. Instead of saying "This button goes here, and this one goes there", you say "This button goes in the top left corner of the window, and this one goes to the right of it". You don't specify how much to the right, just "next to it". The packer handles the job of making it look right.

So lets roll up our sleeves and actually do one

Fire up glade. Find the 'Palette' window - it has lots of small icons in it. These icons are the components that you will use to build your front end. You select a component with a click, and then place it in the target window with another click. The new window button is the top left icon. You always have to create a new window before you can place components.

Before you do anything with your new window, click the button marked GTK+ Additional, and then the 'packer' icon - it's a button with 5 little shaded boxes in it. Now put it in the window you just created with another click.

Unwritten rule

I guess it's not, because I'm writing it, but: Always use a pack object inside a window, frame or other holder. The only time you don't need a packer object is when you are only putting one object, like one button, into a frame. If you are doing this then you are misusing frames.

Now go through the icons and find the menu, frame and status bar icons. If you 'hover' the mouse over an icon, Glade will tell you what that icon is. Add one of each to the window. Notice how they all cluster at the top of the window? Select the menu object by clicking on it. Find the properties window and Set 'Fill X' to true. Zap! The menu now goes from the left edge to the right edge, as it should. Repeat for the frame and statusbar objects.

You can coerce the statusbar to the bottom of the window by setting it's 'side' option to bottom, and anchor it at the southwest. The frame can be persuaded to fill the rest of the window by setting 'Fill Y'. Now resize the window. See how the frame shrinks and grows, but the menu and status bars don't? Just what we wanted.

In general your layout process will go: Create a holder (a window or frame), then place some things in it. Sometimes you will place a couple of frames in a frame. Working out exactly what components you need to put where is a bit of an art, and I recommend starting by copying designs off other programs.

There are some more details, but nothing you can't really figure out by randomly clicking on things in the GUI. I'll leave you with the tip that if you develop big spaces between objects, and you don't want the space there, you probably set 'Expand' to on when you didn't really want to.

Geting a Perl program going

The final thing you'd be wanting to know is how to actually write a perl program with this stuff in it. As you'd expect, it's a bit more work than just reading lines in with $line = <STDIN>, but in some ways it's easier too. You don't need to build an event loop to handle user input.

Every object that you can use in Glade has the option of calling a sub when something happens to it (more properly, an object method). Moving the mouse over an object can call a sub, so can clicking a button certainly. To tell Glade which sub you want to call for an action, select the object, then go to the properties window, Signals tab. Select a signal from the pop-up box. This is the action that will trigger the function. Most of the time it will be 'clicked'.

Enter a name into the 'handler' field. This is the name of the sub that will be called when someone clicks on the object. You will have to write this yourself.

To create your function, you need to go hunting in the code that Glade makes. Save your project, then click the "Write source code" button. Then dive into the project/src directory, and look for a file called If you named your program something different, it will be "something_different/src/ Glade produces a nice module, complete with comments and POD for your window. Look through the file to find the following comment:

#===================================================================== +========= #=== Below are the signal handlers for 'window1' class #===================================================================== +========= sub start_search { my ($class, $data, $object, $instance) = @_; my $form = $__PACKAGE__::all_forms->{$instance}; my $entry_val = $form->{'search_text'}->get_text; print $entry_val; }

Here I copied a function from the FAQ to take some text from a text component (called search_text) when I clicked on the 'Search' button. I added the handler (the subroutine) 'start_search' as shown above. Now when someone clicks the 'Search' button, the start_search sub is called. Gtk calls start_search with some arguments that I pick up in the first line. The rest of the subroutine is some code to get the text from the text box and print it.

Manipulating the interface

Now that you can get signals from the interface, you probably want to send something back, like display a message in a window. This is the point where you need to start reading the 'documentation'. Start with the tutorial though.

In short, the code built by Glade stores references to all the objects in a hash, which you can access to pick out the object you want to work with. Here is an example hash for a project I'm working on.

"window1-1" => { "statusbar1" => bless( { "_gtk" => 14054487 +2 }, 'Gtk::Statusbar' +), "packer1" => bless( { "_gtk" => 140479848 }, 'Gtk::Packer' ), "label1" => bless( { "_gtk" => 140508856 }, 'Gtk::Label' ), "search_button" => bless( { "_gtk" => 14050 +3888 }, 'Gtk::Button' +), "menubar1" => bless( { "_gtk" => 140483920 }, 'Gtk::MenuBar' ), "label4" => bless( { "_gtk" => 140509192 }, 'Gtk::Label' ), "help1_menu" => bless( { "_gtk" => 14049942 +4 }, 'Gtk::Menu' ), "label10" => bless( { "_gtk" => 140508520 }, 'Gtk::Label' ), "label5" => bless( { "_gtk" => 140509360 }, 'Gtk::Label' ), "label6" => bless( { "_gtk" => 140508100 }, 'Gtk::Label' ), "search_text" => bless( { "_gtk" => 1405199 +84 }, 'Gtk::Entry' ), "TOPLEVEL" => bless( { "_gtk" => 140453824 }, 'Gtk::Window' ), "window1" => $VAR1->{"window1-1"}{"TOPLEVEL +"}, "button1" => bless( { "_gtk" => 140503528 }, 'Gtk::Button' ), "preferences1" => bless( { "_gtk" => 140381 +660 }, 'Gtk::MenuItem' + ), "frame1" => bless( { "_gtk" => 140513440 }, 'Gtk::Frame' ), "about1" => bless( { "_gtk" => 140381828 }, 'Gtk::MenuItem' ), "tooltips" => bless( { "_gtk" => 140475936 }, 'Gtk::Tooltips' ), "scrolledwindow1" => bless( { "_gtk" => 140 +523848 }, 'Gtk::Scroll +edWindow' ), "button9" => bless( { "_gtk" => 140504320 }, 'Gtk::Button' ), "searches_seen" => bless( { "_gtk" => 14053 +7272 }, 'Gtk::List' ), "accelgroup" => bless( { "_gtk" => 14047742 +4 }, 'Gtk::AccelGroup' + ), "Placeholder_label" => bless( { "_gtk" => 1 +40509444 }, 'Gtk::Labe +l' ), "help1" => bless( { "_gtk" => 140381744 }, 'Gtk::MenuItem' ) }

I only ever bother to name the objects I plan to work with, so you can see plenty of 'label5's and 'button9's. You can get hold of the object you want if you know it's name: my $obj = $__PACKAGE__::all_forms->{'window1-1'}->{searches_seen}; and then do things like $obj->add( $item );

The final challenge is figuring out what the window name in the hash is. I got it by doing a use Data::Dumper; print Dumper $__PACKAGE__::all_forms;.


Most of the code I pulled out of the FAQ or the tutorial.
Gtk-Perl was written by Kenneth Albanowsky and is now maintained by Paolo Molaro.
Glade was written by Damon Chaplin.
Glade-Perl was written by Dermot Musgrove.

Further reading

Intro to Gnome perl

I didn't believe in evil until I dated it.