<<

GTK Development Using Glade 3

GTK+ is a toolkit, or a collection of libraries, which developers can use to develop GUI applications for , OSX, Windows, and any other platform on which GTK+ is available.

Original Article by Micah Carrick

Table of Contents

Part 1 - Designing a User Interface Using Glade 3 ______1

Quick Overview of GTK+ Concepts ______1

Introduction to Glade3 ______3

Getting Familiar with the Glade Interface______3

Manipulating Widget Properties______5

Specifying Callback Functions for Signals ______6

Adding Widgets to the GtkWindow ______9

How Packing Effects the Layout ______13

Editing the Menu (or Toolbar) ______15

Final Touches to the Main Window ______18

Part 2 - Choosing a for GT K+ Developm ent ______19

Which is the BEST Language? ______19

Language Choice Considerations ______19 A Look at Python vs. C______20

Part 3 ______22

Setting Up Your Development Environment______22

GtkBuilder and LibGlade ______24 The Minimal Application ______25

Compiling and Running the Application ______27

Stepping Through the Code ______29 Including the GTK+ ______29 Initializing the GTK+ Library ______29 Building the Interface with GtkBuilder ______30 Getting References to Widgets From GtkBuilder ______32 Connecting Callback Functions to Signals ______33 Showing the Application Window ______36 In Summary ______37

Part 1| Designing a User Interface Using Glade 3

In part 1 of the GTK+ and Glade3 GUI Programming Tutorial series, we will be designing the (GUI) for a GTK+ text editor application (shown left) which will be used throughout these tutorials. This GUI design will be created using the and is completely independent of the programming language used to implement the design, which will come in subsequent tutorials.

Quick Overview of GTK+ Concepts

If you have no experience with GTK+, you may struggle with some of the concepts I am going to cover. Although I am going to attempt to teach some of these concepts on the fly, it would serve you well to read up on these ideas further, perhaps after working through part 1 of this tutorial. Understanding the fundamental concepts of GTK+ will be instrumental in your ability to effectively use Glade.

First of all, GTK+ is not a programming language. GTK+ is a toolkit, or a collection of libraries, which developers can use to develop GUI applications for Linux, OSX, Windows, and any other platform on which GTK+ is available. It can be thought of in the same terms as MFC or the Win32 API on Windows, and SWT in Java, or (the "other" Linux GUI toolkit used by KDE).

Although GTK+ itself is written in , there are a multitude of language "bindings" allowing to develop GTK+ applications in the language of their choice including C++, Python, , PHP, Ruby, and many others.

GTK+ is based on 3 main libraries: Glib, , and ATK, however, we primarily work with GTK+ and let GTK+ do it's magic with those 3 libraries. GLib wraps most of the standard C library functions for portability (allowing your code to run on Windows and Linux if desired). We use GLib a lot when working in C or C++, which I will explain more thoroughly when implementing our design using C. Higher-level languages such as Python and Ruby won't have to worry about GLib as they have their own standard libraries which provide similar functionality.

GTK+ and associated libraries implement an object oriented approach through GObject. How this works isn't important just yet, and different programming languages will reveal this to you differently, however, it's important to understand that GTK+ uses object orientation (yes, even in C).

Every piece of a GTK+ GUI is comprised of one or more "widgets" which are objects. All widgets will be derived from a base widget called GtkWidget. For example, an application's window is a widget called GtkWindow. The toolbar within that window

1 is a widget called GtkToolbar. Although a GtkWindow is also a GtkWidget, a GtkWidget is not neccesarily a GtkWindow. Child widgets are derived from their parent objects to extend the functionality of that object. These are standard OOP (object oriented programming) concepts (hint: Google search "object oriented programming" if this is a new concept).

We can look at any widget in the GTK+ reference documentation to see which objects it is derived from. In the case of GtkWindow, it looks something like this:

GObject +----GInitiallyUnowned +----GtkObject +----GtkWidget +----GtkContainer +----GtkBin +----GtkWindow

As you can see, a GtkWindow is derived from GtkBin which is derived from GtkContainer, and so on. For your first application, you don't need to worry about anything above the GtkWidget object. The reason this heirarchy is so important is because when you're looking for functions, properties, and signals for any particular widget, you need to realize that the functions, properties, and signals of it's parent objects apply to it as well. In part 2, this will become even more apparent when writing code for this example application.

We also begin to see a naming convention emerge. This is pretty handy. We can easily tell what library an object or function is from. All objects beginning with Gtk are from GTK+. Later, we'll see things like GladeXML which is part of Libglade or GError which is part of GLib. All objects (and thus Widgets) are incamel case. The functions which manipulate these objects are in lower-case with underscores for spaces. For example, gtk_window_set_title() is a function to set the title property of a GtkWindow object.

All the reference documentation you will need is available online from library..org/devel/references, however, it is much easier to use Devhelp which is likely available as a package for your distribution. Devhelp allows you to browse and search the API documentation for the libraries you have installed on your system (assuming you install that libraries documentation as well).

More information on GTK+ and Glib:

 Foundations of GTK+ Development (book)

 GTK+ 2.0 Tutorial

 GTK+ - The GIMP Toolkit

2  GLib Reference Manual

 GTK+ Reference Manual

 GTK+ 2.0 Tutorial (C Programming)

 PyGTK+ 2.0 Tutorial (Python Programming) Introduction to Glade3

Glade is a RAD (Rapid Application Development) tool for designing GTK+ applications. Glade is a GTK+ application itself. It is simply a piece of developers use to simplify the process of laying out an application's interface. Glade creates what will hereforth be refered to a s a "glade file". A glade file is actually an XML file which describes the heirachy of the widgets comprising the interface.

Glade originally generated C code to build the GUI (and you'll still find examples and tutorials doing this). This was later discouraged in favor of using a library, Libglade, to build the interface at run time. And finally, as of Glade3, the old method has become deprecated. That means the ONLY thing glade does is allow you to generate a glade file which describes how the GUI is going to be built. This allows more flexibility with the developer, prevents having to re-compile applications when a minor interface change is needed, and allows more programming languages to be used with Glade.

Glade3 has had significant changes since previous versions such as Glade2. Glade3 has been available for some time and you shouldn't have any problems obtaining it. The for your distribution (yum, , etc.) should have Glade3 available. You should note however, that the package will have 3 in it. Where 'glade' may be the name for the old package, 'glade-3' or 'glade3' will be the package name for the new version on which this tutorial is based. Glade is also available from source at glade.gnome.org. Getting Familiar with the Glade Interface

Start up Glade and let's get familiar with it's interface. I will be referring to various aspects of Glade by the names described here. On the left hand side is the "Palette". The Palette is like that of a graphics editing application. It is a palette of GtkWidgets which you can use to design your application. In the middle area (which is empty when you first start Glade) is the "Editor". This is where you see your design in progress. On the right hand side is the "Inspector" on top and the widget "Properties" below that. The Inspector shows your design as a tree allowing you to access and view the heirarchy of the widgets making up your design. We manipulate various properties of widgets in the Properties tabs, including specifying callback functions for signals (explained later).

3 So, the verfy first thing we're going to do, is create a Toplevel widget and save our file. To do this, Click on the GtkWindow icon in the Palette under the 'Toplevels' section. You should notice a gray box show up inside the Editor area of Glade. This is the workable area of a GtkWindow. The titlebar, close , etc. will be added to the widget by the (ie: GNOME) so we don't see it while editing. We will always start with a toplevel widget in Glade, typically a GtkWindow.

Before going further, save the file as "tutorial.glade".

Now the file you just saved, "tutorial.glade", is an XML file. If you were to open it up in a text editor, it would look something like this:

GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK

4 As you can see, it's just a simple XML file. In part2 we will be using C with Libglade to parse this XML file and generate the UI at run-time. Being XML, this could just as easily be parsed by a Python program or any other language. As we continue to work in Glade, this file will be updated to describe our interface in this XML format any time we save. Exit out of your text editor and return to Glade. Manipulating Widget Properties

The Editor of Glade now shows an empty GtkWindow widget. We are going to manipulate some of the widget's properties. If you look in the Properties pane of Glade, you will see 4 tabs: 'General', 'Packing', 'Common', and 'Signals'. Let's talk about the first 2 tabs. GtkWidgets typically have various properties which manipulate how they function and/or how they are displayed on the screen.

If you look at the reference documentation for a GtkWidget and scroll down to the "Properties" section, you'll see a list of the properties for a GtkWindow. These are typically the properties which appear in the 'General' tab of the Glade properties pane and will vary from widget to widget. The name property exists for every widget in Glade and is what we will use to reference the widget when it comes time to write code for the application. Change the 'name' property of this GtkWindow from "window1" to "window". Then, add the text "GTK+ Text Editor" to the 'Window Title' property.

We'll discuss the 'Packing' tab in a bit, but first, let's look at the 'Common' tab. This tab also contains properties which belong to our GtkWindow, however, we don't see them in the reference documentation for GtkWindow. This is because this is where we set properties which areinherited from parent objects. Looking at the reference documentation for a GtkWidget in the section called "Object Hierarchy", you'll see the objects from which GtkWindow is derived. Click on the GtkContainer link to jump to the reference documentation for a GtkContainer. You'll notice that GtkContainer has a

5 property called "border-width" and we have a property in Glade for "Border width" at the bottom of the 'Common' tab. We'll learn more about what a container widget is later, however, this demonstrates how important that object heirarchy is. Since many widgets are derived from GtkContainer, Glade puts it's properties into the 'Common' tab.

In the "Object Hierarchy" section of the reference documentation for a GtkContainer you'll see that it is derived from a GtkWidget. Now click the GtkWidget link in to jump to the reference documentation for a GtkWidget. The GtkWidget has a bunch of properties, many of which are also shown in the 'Common' tab of Glade's Properties pane. These are properties which are common to all GTK+ widgets since all GTK+ widgets are derivitives of GtkWidget.

Specifying Callback Functions for Signals

Objects emit a "signal" when something that might be useful to the happens. These are similiar to "events" from . If a user does anything within your GUI, chances are they are emitting signals. As a programmer, you choose which signals you want to capture and perform a task, and connect a callback function to that signal.

The first signal we'll learn, and the one which you'll use in just about every GTK+ application you write, is the "destroy" signal emitted by GtkObject. This signal is emitted whenever a GtkObject is destroyed. This is important, because when the user closes the window through the little 'x' up in the title bar or any other means, the widget is destroyed. We want to capture this signal and exit our application properly. This is better illustrated when we write code for this GUI, however, for now, let's just specify the function we want to call when the "destroy" signal is emitted for our GtkWindow.

6 Look at the 'Signals' tab in the Glade Properties pane. You see a tree view where GtkWindow and each of the objects from which it is derived are listed. If you expand the GtkObject, you'll see all the signals emitted by GtkObject. These correspond to the reference documentation for a GtkObject in the "Signals" section.

Under the 'Handler' column, click the gray text "" to begin editing. Select 'on_window_destroy' from the drop down and then hit ENTER. We can type anything we want here, however, glade provides a drop-down list of some of the mroe common callback function naming conventions. How this value is used depends on how the programmer connects signals in the code, however, for this tutorial, we want the GtkWindow's "destroy" signal to be associated with the handler string "on_window_destroy". We'll look at this closer in Part 2.

At this point, we actually have a working GUI. We could write a few lines of code in C, Python, Ruby, or any number of programming languages which would show our empty window and then properly terminate when we clicked the "x" in the titlebar. For this tutorial however, I will be showing you how to build the entire GUI in Glade3 before writing any code. However, to satisfy any possible curiosity, if you would like to see what a simple program looks like that would implement this Glade interface so far...

In C

/* First run tutorial.glade through -builder-convert with this command: gtk-builder-convert tutorial.glade tutorial.

Then save this file as main.c and compile it using this command (those are backticks, not single quotes):

7 gcc -Wall -g -o tutorial main.c `pkg-config --cflags --libs gtk+- 2.0` -export-dynamic

Then execute it using: ./tutorial */ #include

void on_window_destroy (GtkObject *object, gpointer user_data) { gtk_main_quit (); }

int main (int argc, char *argv[]) { GtkBuilder *builder; GtkWidget *window;

gtk_init (&argc, &argv);

builder = gtk_builder_new (); gtk_builder_add_from_file (builder, "tutorial.xml", NULL); window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); gtk_builder_connect_signals (builder, NULL);

g_object_unref (G_OBJECT (builder));

gtk_widget_show (window); gtk_main ();

return 0; }

In Python (note: you must set the 'visible' property of 'window' to "Yes" in the 'Common' properties tab in Glade)

#!/usr/bin/env python

# First run tutorial.glade through gtk-builder-convert with this command:

8