GTK Overview

only for RuBoard - do not distribute or recompile

GTK+ Overview

GTK+ is built on the concept of inheritance (or, more correctly, sub-classing), although the toolkit itself is C-based. Widgets are the basis of other widgets, and some widgets are container widgets. Even the form or main window of a program is a widget. Widgets emit signals ( events ) that are caught and handled by the signal handler and passed to the correct callback, or function.

The Phases of a GTK+ Program

GTK+ programs operate in several distinct phases. First, you must create the widgets and set them to display as needed. You must then tell the program what signal to look for from which widget, and what function to run when that signal is emitted . Then you must explicitly show the widget (or show its parent, which will then show the child widget). When the widget is no longer needed (such as when the application terminates), you need to explicitly destroy the widget.

Object Hierarchy

Every object in the GTK+ widget set is derived from another object, with the root object being the GtkObject object.

The following is the object hierarchy for quite possibly the most pedestrian of all GUI controls: the lowly command button:

 GtkObject    +-GtkWidget        +-GtkContainer            +-GtkBin                +-GtkButton 

And so on. In fact, the GtkToggleButton, GtkCheckButton, and GtkRadioButton are all descendants of the GtkButton type. This is called inheritance, and it allows the programmer to use behaviors already defined for an object, to override default behaviors, or create entirely new ones.

The GTK Web site (www.gtk.org) maintains a full object hierarchy tree. Check there for the latest widgets and up-to-date information on their uses.

GLib and GDK

These are the building blocks on which GTK+ is built. GLib deals primarily with unglamorous but necessary things like memory, strings, and so on. GDK is the toolkit used for drawing ”in this case, drawing of widgets.

GLib

GLib is a set of routines that work with more primitive types; it is actually closer to C than to a GUI toolkit. However, it is fundamentally stronger than C. Glib provides a standard set of macros, functions, and datatypes. For example, it can provide datatypes of certain length no matter what the underlying hardware is, thus solving some major portability issues.

For example, there is a GLib function called g_malloc() . It is a replacement for C s malloc() . The advantage is that you do not need to check the return value; that is done by the function itself. To take it a step further, consider g_malloc0() . It zeroes out the memory for you.

The function prototypes are:

 gpointer g_malloc ( gulong size );  gpointer g_malloc0 ( gulong size); 

Notice all those g s. Everything has been converted to GLib. The same is true of string handling functions. GLib defines a new type called GString. Unlike a normal C string, a GString can grow automatically, and it is null- terminated . This protects you from buffer overflow errors.

The entire GLib library has been written for such use; if you are new to C, making use of GLib s types instead of native C types will help you produce better and safer code.

GDK

GDK stands for the GNOME Drawing Kit. It is primarily used for drawing graphics. For example, every command button that appears on the screen has to be drawn; this is where GDK comes in. It provides the different looks: non-active, active, pushed , selected, and so on. It also provides widgets for drawing things such as pie graphs and charts . You will see these later as gdk_ functions instead of gtk_ functions.

Widgets, Not Controls

Widgets are the fundamental building blocks of GTK+. A widget can be any object, seen or unseen. It may or may not have events and properties. In VB, they are called controls; here they are called widgets.

Table 2.1 compares common VB controls to their ( closest ) GTK+ counterparts. A more detailed discussion of widgets follows later in this chapter.

Table  2.1. VB Basic Controls and Their Corresponding GTK+ Widgets

VB Control

GTK+ Widget

Comments

PictureBox

GtkImage, GtkPixmap

GtkPixmap is normally used to display icons.

Label

GtkLabel

Very similar in form and function.

TextBox

GtkEntry, GtkText

One for single line, the other for multiple line text.

Frame

GtkFrame, GtkAspectFrame

Does not automatically group radio buttons likeVB does.

CommandButton

GtkButton

Very similar in form and function.

CheckBox

GtkCheckButton, GtkToggleButton

Toggle button is a separate widget rather than a property of the check box.

OptionButton

GtkRadioButton

Frames do not automatically group; must be explicitly set.

ComboBox

GtkCombo

An entry widget with a pull-down list.

ListBox

GtkCList, GtkList

Multi-column list (GtkCList) is a separate widget rather than a property of GtkList.

HScrollBar

GtkHScrollbar

Very similar toVB.

VScrollBar

GtkVScrollbar

Very similar toVB.

Timer

GTimer

Gtimer is a GLib object

DriveListBox

N/A

No direct correlation; the idea of a named drive does not exist in Linux.

DirListBox

GtkFileSelection

Can be used to select a directory.

FileListBox

GtkFileSelection

Can also be used to select a directory.

Shape

N/A

GDK methods provide for shapes and lines.

Line

N/A

Also see GDK library and methods.

Image

GtkImage

Displays a GdkImage widget.

Data

GtkCList

Has no integrated data connectivity.

OLE

N/A

No correlation in GTK+.

Tab Control (third party)

GtkNotebook

Tabs can be put on any edge: top, bottom, left, or right.

Form

GtkWindow plus GtkLayout

Fails to take advantage of the integrated resize capabilities of GTK+.

As you can see, some VB controls have no direct counterparts; that s okay, because some widgets have no corresponding controls. In all, GTK+ provides more than 60 widgets.

Signals and Callbacks

These are what VB developers call events, although an event in VB includes what GTK+ separates into an event, a signal, and a callback (the function to be executed). An event is what you are used to: button clicked, mouse over, and so on. The event causes a signal to be emitted from the widget. That signal is tied to a callback function, which contains the code that s actually to be executed when the button is pushed (for example). The connection mechanism is the GTK+ signal handler ”the function gtk_main(), which is usually the last step of a GTK+ program. In GTK+, you have to connect signals to callbacks yourself. This will be covered in depth later in the book.

GTK+ programs will always have a gtk_main() function. Its purpose is to monitor for emitted signals and then initiate the correct callback functions. For further demonstration, see Listings 2.1 and 2.2

Hello World ”The Program

For those new to the GTK+ widget set, this Hello World program may prove very instructive. The following program attempts to demonstrate the near-minimum for creating and running a GTK+ program.

Hello World, in Listing 2.1, instantiates a single window and a single command button. It connects the program-terminate function call to the pushed event of the command button. Note that you could have made this program even tighter by omitting the command button and the gtk_main_quit() call. In that case, the user would have had to click the window-close button in the upper-left corner of the window (the X button that is normally instantiated as part of the window, even in X- Windows ). That action would close the window, but the user would still have to press Ctrl+C to end the GTK+ program (which you also might have to do if your GTK+ program hangs for any reason).

Listing 2.1 Minimal GTK+ Program
 01 #include <gtk/gtk.h>  02  03 void cmd_button_clicked()  04 { 05 gtk_main_quit();  06 }  07  08 int main (int argc, char *argv[])  09 { 10    GtkWidget *frm_main, *cmd_button;  11  12    gtk_init(&argc, &argv);  13  14    frm_main = gtk_window_new(GTK_WINDOW_TOPLEVEL);  15  16    cmd_button = gtk_button_new_with_label("Hello World.\nClick to close.");  17  18    gtk_signal_connect(GTK_OBJECT(cmd_button),  19                       "clicked",  20                       GTK_SIGNAL_FUNC(cmd_button_clicked),  21                       NULL);  22  23    gtk_container_add(GTK_CONTAINER(frm_main), cmd_button);  24  25    gtk_widget_show_all(frm_main);  26  27    gtk_main();  28  29    return 0;  30 } 

As you can see, this is a very small and rather useless program. The important parts are outlined here:

Line 01: Include the GTK+ widgets for compilation.

Line 03: The event handler for when the command button is clicked.

Line 08: The main body of the program.

Line 10: Declare the objects, in this case, one window and one command button.

Line 12: Initialize the GTK+ system.

Line 14: Create the form; however, it is still not visible!

Line 16: Create the command button; again, it is not visible.

Line 18: Connect the function on line 03 with the clicked event of the command button.

Line 23: Add the button to the window (the container object).

Line 25: Make all widgets visible. (Until now, all widgets have been invisible.) This action is known to substantially increase the usefulness of any GUI application.

Line 27: Start the GTK+ event loop, which monitors for signals emitted from the widgets and fires the correct event handlers.

Line 29: Exit status; required for every C program.

As you can see, this is not terribly difficult ( for C, some of you are saying).

Hello World ”The Compile

From the command line, send the following:

 % gcc -Wall -g listing.2.1.c -o HelloWorld `gtk-config --cflags` `gtk-config --libs` 

This should produce an executable called HelloWorld in your current directory. You could have just as easily made it HelloWorld.exe by changing the filename after the output flag ( -o ). (You can omit -o HelloWorld from the preceding command; if you do, it will create a file called a.out by default, as the executable.) The -Wall instructs the gcc compiler to display all warnings, and the -g option instructs the compiler to include debug information for use with a debugger. If you want to avoid retyping, you could put the preceding line into a shell script (the Linux equivalent of a batch file, but it s not as good as a makefile). For example, if the shell script is named build.2.1 , you would execute it by sending this command:

 % ./build.2.1 

In this case, build.2.1 is the name of the file that has the gcc line in it. Then, to run the program, send:

 % ./HelloWorld 

The window should come up. The ./ at the beginning of the above commands tells Linux to look in the current directory, not to search your default path for the file. The `gtk-config ` part of the command line is covered in the next section.

gtk-config

You may have noticed and wondered about the `gtk-config ` on the command line above. gtk-config is a program that expands to fill in flags that gcc will use as part of the compile. You could also think of it as a macro because it stands for something else that will be expanded at the time the information is needed.

This is important: The gtk-config program is surrounded by back ticks, not single quotation marks! If you search the GTK+ mailing list archives, you will see how many people are tripped up by this! The back tick character (`) is located in the upper-left corner of most keyboards and usually shares its key with the tilde character (~). The back ticks tell gcc to execute the enclosed program. You can see this for yourself from the following command line:

 % gtk-config --cflags 

You will see that this expands to the flags gcc needs to compile a GTK+ program.

VB s Form Reincarnated as GtkWindow Plus GtkFixed or GtkLayout

Until this section, when dealing with GTK+, you have not dealt with GTK+ as a container widget set, although that is the primary paradigm of GTK+. That is, a window is a container: You add child widgets to it, and those child widgets fill the space they are given and automatically resize and adjust when their parent widget resizes or otherwise changes shape. Notice that this happens in HelloWorld (see Listing 2.1). The window widget has one child widget. If you resize the window, the button widget changes shape as well. GTK+ is designed to work this way, and a number of child widgets are designed to take advantage of this behavior.

However, many VB developers who are new to GTK+ may initially be attracted to the GtkFixed or GtkLayout widget because of how closely they resemble the development environments from which they came. Unlike most other widgets in GTK+, these do not resize automatically, at least not for their child widgets. Both are grid widgets on which you can lay out other child widgets, but when the size of the window changes, the child widgets placed on the GtkFixed or GtkLayout widget will not change size or location. This will all be very familiar to developers coming from Visual Basic or C++. The primary difference between the GtkFixed widget and the GtkLayout widget is that the GtkLayout widget has scroll bars that allow you to move around within the window if the window size becomes smaller than the displayable child widgets. The GtkFixed widget will simply cut the child widgets out of view. For the user to see them (or even know they are there!), the user has to resize the window.

A Note of Caution

By using the GtkFixed or GtkLayout widget, you might have an easier start, but you will probably run into a problem getting your window widget to default to the right size to properly display all the child widgets correctly. Be sure to thoroughly study the functions for sizing windows.

In Figure 2.1, notice the grid of dots for placing widgets. This looks very familiar to VB developers; when this window size is changed, the child widgets placed on the grid will not change size. VB developers new to GTK+ should know that this type of application is the exception; the overriding paradigm of GTK+ is what a VB developer would call an automatic resizer control. By using the container paradigm of GTK+, you get this automatic resizer effect without the need for any special widget. GtkLayout certainly has its uses, but in the long run, I suspect you ll be happier with your GTK+ programs if you adapt to the container-resize paradigm. I mention this because when I was a VB developer learning about GTK+, that was my initial reaction. In the long run, though, I found that letting GTK+ resize for me was easier and better. Also note that this figure was created using Glade; see Chapter 5, Glade for VB Developers, for more information.

Figure 2.1. GtkWindow plus GtkLayout.
graphics/02fig01.gif

GTK+ Widgets Never Need Tab Order Adjustments

Actually, the fact that GTK+ Widgets never need tab order adjustments can be either a blessing or a curse. Anyone who has developed VB applications for long learns to hate setting the tab order (that is, the order the cursor follows from control to control when the user presses the Tab button). For industrial-strength application dataentry tasks , this can become a very important issue because users will quickly want to move from the mouse to the keyboard to navigate the form. This was one of the things the old DOS screens could do very well. Once the user got used to a certain set of keystrokes, he could enter massive amounts of data very quickly by keying ahead of the screen, and the buffer would hold the key strokes and process them in time.

The whole point of this, however, is that in GTK+, the tab order is set for you: right-to-left and top-to-bottom, just as you would read the controls on the screen if you were inclined to do so. Actually, GTK+ doesn t really have anything analogous to the tab order; it is handled for you. As I said at the start, though, this can be a blessing ”but it can also be a curse. You decide. It can be a blessing because you do not have to code for tab order; it can be a curse because you cannot control the order.

only for RuBoard - do not distribute or recompile


MySQL Building User Interfaces
MySQL: Building User Interfaces (Landmark)
ISBN: 073571049X
EAN: 2147483647
Year: 2001
Pages: 119

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net