gtk_tut.sgml 572 KB
Newer Older
1 2 3 4 5 6 7
<!doctype linuxdoc system>

<!-- This is the tutorial marked up in SGML
     (just to show how to write a comment)

<title>GTK v1.2 Tutorial
Tony Gale <tt><htmlurl url=""
12 13
Ian Main <tt><htmlurl url=""
<date>February 21st, 1999
15 16 17 18 19 20 21 22 23 24
This is a tutorial on how to use GTK (the GIMP Toolkit) through its C

<!-- Table of contents -->
<!-- Older versions of this tutorial did not have a table of contents,
     but the tutorial is now so large that having one is very useful. -->
25 26 27 28 29

<!-- ***************************************************************** -->
<!-- ***************************************************************** -->
30 31 32 33 34 35 36 37 38 39 40 41 42
GTK (GIMP Toolkit) is a library for creating graphical user
interfaces. It is licensed using the LGPL license, so you can develop
open software, free software, or even commercial non-free software
using GTK without having to spend anything for licenses or royalties.

It's called the GIMP toolkit because it was originally written for
developing the General Image Manipulation Program (GIMP), but GTK has
now been used in a large number of software projects, including the
GNU Network Object Model Environment (GNOME) project. GTK is built on
top of GDK (GIMP Drawing Kit) which is basically a wrapper around the
low-level functions for accessing the underlying windowing functions
(Xlib in the case of X windows). The primary authors of GTK are:

43 44 45 46 47 48 49 50 51
<item> Peter Mattis   <tt><htmlurl url=""
<item> Spencer Kimball <tt><htmlurl url=""
<item> Josh MacDonald <tt><htmlurl url=""

GTK is essentially an object oriented application programmers
interface (API). Although written completely in C, it is implemented
54 55
using the idea of classes and callback functions (pointers to

There is also a third component called glib which contains a few
replacements for some standard calls, as well as some additional
59 60
functions for handling linked lists etc. The replacement functions are
used to increase GTK's portability, as some of the functions
implemented here are not available or are nonstandard on other unixes
such as g_strerror(). Some also contain enhancements to the libc
63 64
versions, such as g_malloc that has enhanced debugging utilities.

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
This tutorial describes the C interface to GTK. There are GTK
bindings for many other languages including C++, Guile, Perl, Python,
TOM, Ada95, Objective C, Free Pascal, and Eiffel. If you intend to
use another language's bindings to GTK, look at that binding's
documentation first. In some cases that documentation may describe
some important conventions (which you should know first) and then
refer you back to this tutorial. There are also some cross-platform
APIs (such as wxWindows and V) which use GTK as one of their target
platforms; again, consult their documentation first.

If you're developing your GTK application in C++, a few extra notes
are in order. There's a C++ binding to GTK called GTK--, which
provides a more C++-like interface to GTK; you should probably look
into this instead. If you don't like that approach for whatever
reason, there are two alternatives for using GTK. First, you can use
only the C subset of C++ when interfacing with GTK and then use the C
interface as described in this tutorial. Second, you can use GTK and
C++ together by declaring all callbacks as static functions in C++
classes, and again calling GTK using its C interface. If you choose
this last approach, you can include as the callback's data value a
pointer to the object to be manipulated (the so-called "this" value).
Selecting between these options is simply a matter of preference,
since in all three approaches you get C++ and GTK. None of these
approaches requires the use of a specialized preprocessor, so no
matter what you choose you can use standard C++ with GTK.

This tutorial is an attempt to document as much as possible of GTK,
but it is by no means complete. This tutorial assumes a good
understanding of C, and how to create C programs. It would be a great
benefit for the reader to have previous X programming experience, but
it shouldn't be necessary. If you are learning GTK as your first
widget set, please comment on how you found this tutorial, and what
you had trouble with. Note that there is also a C++ API for GTK
(GTK--) in the works, so if you prefer to use C++, you should look
into this instead. There are also Objective C, ADA, Guile and other
language bindings available, but I don't follow these.

This document is a 'work in progress'. Please look for updates on
103 104 105 <htmlurl url=""

106 107 108 109
I would very much like to hear of any problems you have learning GTK
from this document, and would appreciate input as to how it may be
improved. Please see the section on <ref id="sec_Contributing"
name="Contributing"> for further information.
110 111 112 113 114 115

<!-- ***************************************************************** -->
<sect>Getting Started
<!-- ***************************************************************** -->

116 117 118 119 120 121
The first thing to do of course, is download the GTK source and
install it. You can always get the latest version from in
/pub/gtk. You can also view other sources of GTK information on <htmlurl url=""
name="">. GTK uses GNU autoconf for configuration.
Once untar'd, type ./configure --help to see a list of options.

123 124 125
Th GTK source distribution also contains the complete source to all of
the examples used in this tutorial, along with Makefiles to aid

127 128 129
To begin our introduction to GTK, we'll start with the simplest
program possible. This program will create a 200x200 pixel window and
has no way of exiting except to be killed using the shell.
130 131

132 133
/* example-start base base.c */

134 135
#include <gtk/gtk.h>

136 137
int main( int   argc,
          char *argv[] )
138 139 140 141 142 143
    GtkWidget *window;
    gtk_init (&amp;argc, &amp;argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_show  (window);
145 146 147
    gtk_main ();
150 151 152 153 154 155
/* example-end */

You can compile the above program with gcc using:
gcc base.c -o base `gtk-config --cflags --libs`
156 157

158 159
The meaning of the unusual compilation options is explained below.

All programs will of course include gtk/gtk.h which declares the
variables, functions, structures etc. that will be used in your GTK

164 165 166 167 168 169 170
The next line:

gtk_init (&amp;argc, &amp;argv);

calls the function gtk_init(gint *argc, gchar ***argv) which will be
called in all GTK applications. This sets up a few things for us such
as the default visual and color map and then proceeds to call
gdk_init(gint *argc, gchar ***argv). This function initializes the
library for use, sets up default signal handlers, and checks the
175 176
arguments passed to your application on the command line, looking for
one of the following:
177 178

179 180 181 182 183 184
<item> <tt/--gtk-module/
<item> <tt/--g-fatal-warnings/
<item> <tt/--gtk-debug/
<item> <tt/--gtk-no-debug/
<item> <tt/--gdk-debug/
<item> <tt/--gdk-no-debug/
185 186
<item> <tt/--display/
<item> <tt/--sync/
<item> <tt/--no-xshm/
188 189
<item> <tt/--name/
<item> <tt/--class/

192 193
It removes these from the argument list, leaving anything it does not
recognize for your application to parse or ignore. This creates a set
of standard arguments accepted by all GTK applications.

196 197 198 199 200 201 202 203 204
The next two lines of code create and display a window.

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_show (window);

The GTK_WINDOW_TOPLEVEL argument specifies that we want the window to
undergo window manager decoration and placement. Rather than create a
205 206
window of 0x0 size, a window without children is set to 200x200 by
default so you can still manipulate it.

208 209
The gtk_widget_show() function lets GTK know that we are done setting
the attributes of this widget, and that it can display it.

211 212 213
The last line enters the GTK main processing loop.

  gtk_main ();
215 216

217 218 219 220
gtk_main() is another call you will see in every GTK 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. In our simple example however, events are ignored.
221 222 223 224

<!-- ----------------------------------------------------------------- -->
<sect1>Hello World in GTK
225 226
Now for a program with a widget (a button).  It's the classic
hello world a la GTK.
227 228

/* example-start helloworld helloworld.c */
230 231 232

#include <gtk/gtk.h>

233 234 235 236
/* This is a callback function. The data arguments are ignored
 * in this example. More on callbacks below. */
void hello( GtkWidget *widget,
            gpointer   data )
237 238 239 240
    g_print ("Hello World\n");

241 242 243
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
245 246
    /* If you return FALSE in the "delete_event" signal handler,
     * GTK will emit the "destroy" signal. Returning TRUE means
     * you don't want the window to be destroyed.
     * This is useful for popping up 'are you sure you want to quit?'
     * type dialogs. */

251 252
    g_print ("delete event occurred\n");

    /* Change TRUE to FALSE and the main window will be destroyed with
     * a "delete_event". */

257 258

259 260 261
/* Another callback */
void destroy( GtkWidget *widget,
              gpointer   data )
264 265

266 267
int main( int   argc,
          char *argv[] )
268 269 270 271 272
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
273 274 275
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
    gtk_init(&amp;argc, &amp;argv);
276 277 278 279
    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
280 281 282 283 284
    /* When the window is given the "delete_event" signal (this is given
     * by the window manager, usually by the 'close' option, or on the
     * titlebar), we ask it to call the delete_event () function
     * as defined above. The data passed to the callback
     * function is NULL and is ignored in the callback function. */
285 286 287
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);
    /* Here we connect the "destroy" event to a signal handler.  
     * This event occurs when we call gtk_widget_destroy() on the window,
     * or if we return 'FALSE' in the "delete_event" callback. */
291 292 293
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
			GTK_SIGNAL_FUNC (destroy), NULL);
    /* Sets the border width of the window. */
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
    /* Creates a new button with the label "Hello World". */
298 299 300
    button = gtk_button_new_with_label ("Hello World");
    /* When the button receives the "clicked" signal, it will call the
301 302
     * function hello() passing it NULL as its argument.  The hello()
     * function is defined above. */
303 304 305 306
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (hello), NULL);
    /* This will cause the window to be destroyed by calling
     * gtk_widget_destroy(window) when "clicked".  Again, the destroy
308 309 310 311 312
     * signal could come from here, or the window manager. */
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
			       GTK_SIGNAL_FUNC (gtk_widget_destroy),
			       GTK_OBJECT (window));
    /* This packs the button into the window (a gtk container). */
314 315
    gtk_container_add (GTK_CONTAINER (window), button);
    /* The final step is to display this newly created widget. */
317 318 319 320 321
    gtk_widget_show (button);
    /* and the window */
    gtk_widget_show (window);
322 323 324
    /* All GTK applications must have a gtk_main(). Control ends here
     * and waits for an event to occur (like a key press or
     * mouse event). */
325 326
    gtk_main ();
/* example-end */
330 331 332 333 334 335 336 337

<!-- ----------------------------------------------------------------- -->
<sect1>Compiling Hello World
To compile use:

gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
    `gtk-config --libs`
341 342 343 344 345 346

This uses the program <tt>gtk-config</>, which comes with gtk. This
program 'knows' what compiler switches are needed to compile programs
that use gtk. <tt>gtk-config --cflags</> will output a list of include
directories for the compiler to look in, and <tt>gtk-config --libs</>
will output the list of libraries for the compiler to link with and
347 348 349
the directories to find them in. In the aboce example they could have
been combined into a single instance, such as
`gtk-config --cflags --libs`.

351 352 353
Note that the type of single quote used in the compile command above
is significant.

The libraries that are usually linked in are:
355 356 357
<item>The GTK library (-lgtk), the widget library, based on top of GDK.
<item>The GDK library (-lgdk), the Xlib wrapper.
358 359
<item>The gmodule library (-lgmodule), which is used to load run time
<item>The glib library (-lglib), containing miscellaneous functions, only
361 362 363
g_print() is used in this particular example. GTK is built on top
of glib so you will always require this library. See the section on 
<ref id="sec_glib" name="glib"> for details.
<item>The Xlib library (-lX11) which is used by GDK.
<item>The Xext library (-lXext). This contains code for shared memory
pixmaps and other X extensions.
<item>The math library (-lm). This is used by GTK for various purposes.
368 369 370 371 372

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Signals and Callbacks
373 374 375 376
Before we look in detail at <em>helloworld</em>, we'll discuss signals
and callbacks. GTK is an event driven toolkit, which means it will
sleep in gtk_main until an event occurs and control is passed to the
appropriate function.

378 379 380 381 382
This passing of control is done using the idea of "signals". When an
event occurs, such as the press of a mouse button, the appropriate
signal will be "emitted" by the widget that was pressed.  This is how
GTK does most of its useful work. There are a set of signals that all
widgets inherit, such as "destroy", and there are signals that are
383 384
widget specific, such as "toggled" on a toggle button.

385 386 387
To make a button perform an action, we set up a signal handler to
catch these signals and call the appropriate function. This is done by
using a function such as:
388 389

390 391 392 393
gint gtk_signal_connect( GtkObject     *object,
                         gchar         *name,
                         GtkSignalFunc  func,
                         gpointer       func_data );

396 397 398 399
Where the first argument is the widget which will be emitting the
signal, and the second, the name of the signal you wish to catch. The
third is the function you wish to be called when it is caught, and the
fourth, the data you wish to have passed to this function.

The function specified in the third argument is called a "callback
function", and should generally be of the form:
403 404

405 406
void callback_func( GtkWidget *widget,
                    gpointer   callback_data );

409 410 411
Where the first argument will be a pointer to the widget that emitted
the signal, and the second, a pointer to the data given as the last
argument to the gtk_signal_connect() function as shown above.
412 413

Note that the above form for a signal callback function declaration is
414 415 416
only a general guide, as some widget specific signals generate
different calling parameters. For example, the GtkCList "select_row"
signal provides both row and column parameters.

Another call used in the <em>helloworld</em> example, is:
419 420

421 422 423 424
gint gtk_signal_connect_object( GtkObject     *object,
                                gchar         *name,
                                GtkSignalFunc  func,
                                GtkObject     *slot_object );

427 428 429
gtk_signal_connect_object() is the same as gtk_signal_connect() except
that the callback function only uses one argument, a pointer to a GTK
object. So when using this function to connect signals, the callback
should be of the form:
431 432

void callback_func( GtkObject *object );

436 437 438 439
Where the object is usually a widget. We usually don't setup callbacks
for gtk_signal_connect_object however. They are usually used to call a
GTK function that accepts a single widget or object as an argument, as
is the case in our <em>helloworld</em> example.

441 442 443 444 445 446
The purpose of having two functions to connect signals is simply to
allow the callbacks to have a different number of arguments. Many
functions in the GTK library accept only a single GtkWidget pointer as
an argument, so you want to use the gtk_signal_connect_object() for
these, whereas for your functions, you may need to have additional
data supplied to the callbacks.

448 449 450
<!-- ----------------------------------------------------------------- -->
451 452 453
In addition to the signal mechanism described above, there are a set
of <em>events</em> that reflect the X event mechanism. Callbacks may
also be attached to these events. These events are:
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486

<item> event
<item> button_press_event
<item> button_release_event
<item> motion_notify_event
<item> delete_event
<item> destroy_event
<item> expose_event
<item> key_press_event
<item> key_release_event
<item> enter_notify_event
<item> leave_notify_event
<item> configure_event
<item> focus_in_event
<item> focus_out_event
<item> map_event
<item> unmap_event
<item> property_notify_event
<item> selection_clear_event
<item> selection_request_event
<item> selection_notify_event
<item> proximity_in_event
<item> proximity_out_event
<item> drag_begin_event
<item> drag_request_event
<item> drag_end_event
<item> drop_enter_event
<item> drop_leave_event
<item> drop_data_available_event
<item> other_event

487 488 489 490 491
In order to connect a callback function to one of these events, you
use the function gtk_signal_connect, as described above, using one of
the above event names as the <tt/name/ parameter. The callback
function for events has a slightly different form than that for
492 493 494 495 496 497 498

void callback_func( GtkWidget *widget,
                    GdkEvent  *event,
                    gpointer   callback_data );

499 500 501 502 503 504
GdkEvent is a C <tt/union/ structure whose type will depend upon which
of the above events has occurred. In order for us to tell which event
has been issued each of the possible alternatives has a <tt/type/
parameter which reflects the event being issued. The other components
of the event structure will depend upon the type of the
event. Possible values for the type are:
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541

  GDK_OTHER_EVENT	/* Deprecated, use filters instead */

So, to connect a callback function to one of these events we would use
something like:
543 544 545 546 547 548 549

gtk_signal_connect( GTK_OBJECT(button), "button_press_event",

550 551 552 553
This assumes that <tt/button/ is a GtkButton widget. Now, when the
mouse is over the button and a mouse button is pressed, the function
<tt/button_press_callback/ will be called. This function may be
declared as:
554 555 556 557 558 559 560

static gint button_press_event (GtkWidget      *widget, 
                                GdkEventButton *event,
                                gpointer        data);

561 562 563
Note that we can declare the second argument as type
<tt/GdkEventButton/ as we know what type of event will occur for this
function to be called.

565 566 567 568 569
The value returned from this function indicates whether the event
should be propagated further by the GTK event handling
mechanism. Returning TRUE indicates that the event has been handled,
and that it should not propagate further. Returning FALSE continues
the normal event handling.  See the section on
570 571 572 573 574 575
<ref id="sec_Adv_Events_and_Signals"
name="Advanced Event and Signal Handling"> for more details on this
propagation process.

For details on the GdkEvent data types, see the appendix entitled
<ref id="sec_GDK_Event_Types" name="GDK Event Types">.

577 578 579 580
<!-- ----------------------------------------------------------------- -->
<sect1>Stepping Through Hello World
Now that we know the theory behind this, lets clarify by walking through 
the example <em>helloworld</em> program.

Here is the callback function that will be called when the button is
584 585 586
"clicked". We ignore both the widget and the data in this example, but
it is not hard to do things with them. The next example will use the
data argument to tell us which button was pressed.
587 588

589 590
void hello( GtkWidget *widget,
            gpointer   data )
591 592 593 594 595
    g_print ("Hello World\n");

596 597 598 599
The next callback is a bit special. The "delete_event" occurs when the
window manager sends this event to the application. We have a choice
here as to what to do about these events. We can ignore them, make
some sort of response, or simply quit the application.

601 602 603 604 605
The value you return in this callback lets GTK know what action to
take.  By returning TRUE, we let it know that we don't want to have
the "destroy" signal emitted, keeping our application running. By
returning FALSE, we ask that "destroy" is emitted, which in turn will
call our "destroy" signal handler.
606 607

608 609 610
gint delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
    g_print ("delete event occurred\n");

    return (TRUE); 
615 616 617

618 619 620
Here is another callback function which causes the program to quit by
calling gtk_main_quit(). This function tells GTK that it is to exit
from gtk_main when control is returned to it.

623 624
void destroy( GtkWidget *widget,
              gpointer   data )
625 626 627 628
    gtk_main_quit ();

630 631
I assume you know about the main() function... yes, as with other
applications, all GTK applications will also have one of these.

634 635
int main( int   argc,
          char *argv[] )
636 637

639 640
This next part, declares a pointer to a structure of type
GtkWidget. These are used below to create a window and a button.

642 643 644 645
    GtkWidget *window;
    GtkWidget *button;

647 648 649 650 651
Here is our gtk_init again. As before, this initializes the toolkit,
and parses the arguments found on the command line. Any argument it
recognizes from the command line, it removes from the list, and
modifies argc and argv to make it look like they never existed,
allowing your application to parse the remaining arguments.

653 654 655
    gtk_init (&amp;argc, &amp;argv);

657 658 659 660
Create a new window. This is fairly straight forward. Memory is
allocated for the GtkWidget *window structure so it now points to a
valid structure. It sets up a new window, but it is not displayed
until we call gtk_widget_show(window) near the end of our program.

662 663 664
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
665 666

Here is an example of connecting a signal handler to an object, in
667 668
this case, the window. Here, the "destroy" signal is caught. This is
emitted when we use the window manager to kill the window (and we
return FALSE in the "delete_event" handler), or when we use the
670 671
gtk_widget_destroy() call passing in the window widget as the object
to destroy. By setting this up, we handle both cases with a single
call. Here, it just calls the destroy() function defined above with a
NULL argument, which quits GTK for us.

675 676 677
The GTK_OBJECT and GTK_SIGNAL_FUNC are macros that perform type
casting and checking for us, as well as aid the readability of the

679 680
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
                        GTK_SIGNAL_FUNC (destroy), NULL);

684 685 686 687
This next function is used to set an attribute of a container object.
This just sets the window so it has a blank area along the inside of
it 10 pixels wide where no widgets will go. There are other similar
functions which we will look at in the section on
<ref id="sec_setting_widget_attributes" name="Setting Widget Attributes">

And again, GTK_CONTAINER is a macro to perform type casting.

    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

696 697 698 699
This call creates a new button. It allocates space for a new GtkWidget
structure in memory, initializes it, and makes the button pointer
point to it. It will have the label "Hello World" on it when

701 702 703
    button = gtk_button_new_with_label ("Hello World");

705 706 707 708 709
Here, we take this button, and make it do something useful. We attach
a signal handler to it so when it emits the "clicked" signal, our
hello() function is called. The data is ignored, so we simply pass in
NULL to the hello() callback function. Obviously, the "clicked" signal
is emitted when we click the button with our mouse pointer.
710 711 712

    gtk_signal_connect (GTK_OBJECT (button), "clicked",
                        GTK_SIGNAL_FUNC (hello), NULL);

716 717 718 719 720 721 722 723 724 725
We are also going to use this button to exit our program. This will
illustrate how the "destroy" signal may come from either the window
manager, or our program. When the button is "clicked", same as above,
it calls the first hello() callback function, and then this one in the
order they are set up. You may have as many callback functions as you
need, and all will be executed in the order you connected
them. Because the gtk_widget_destroy() function accepts only a
GtkWidget *widget as an argument, we use the
gtk_signal_connect_object() function here instead of straight
726 727

728 729 730
    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
                               GTK_OBJECT (window));

733 734 735 736 737 738
This is a packing call, which will be explained in depth later on. But
it is fairly easy to understand. It simply tells GTK that the button
is to be placed in the window where it will be displayed. Note that a
GTK container can only contain one widget. There are other widgets,
that are described later, which are designed to layout multiple
widgets in various ways.
740 741 742
    gtk_container_add (GTK_CONTAINER (window), button);

Now we have everything set up the way we want it to be. With all the
signal handlers in place, and the button placed in the window where it
746 747 748 749
should be, we ask GTK to "show" the widgets on the screen. The window
widget is shown last so the whole window will pop up at once rather
than seeing the window pop up, and then the button form inside of
it. Although with such a simple example, you'd never notice.

751 752 753 754 755
    gtk_widget_show (button);

    gtk_widget_show (window);

757 758 759
And of course, we call gtk_main() which waits for events to come from
the X server and will call on the widgets to emit signals when these
events come.

761 762 763
    gtk_main ();

And the final return. Control returns here after gtk_quit() is called.

767 768 769
    return 0;

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
Now, when we click the mouse button on a GTK button, the widget emits
a "clicked" signal. In order for us to use this information, our
program sets up a signal handler to catch that signal, which
dispatches the function of our choice. In our example, when the button
we created is "clicked", the hello() function is called with a NULL
argument, and then the next handler for this signal is called. This
calls the gtk_widget_destroy() function, passing it the window widget
as its argument, destroying the window widget. This causes the window
to emit the "destroy" signal, which is caught, and calls our destroy()
callback function, which simply exits GTK.

Another course of events, is to use the window manager to kill the
window. This will cause the "delete_event" to be emitted. This will
call our "delete_event" handler. If we return TRUE here, the window
will be left as is and nothing will happen. Returning FALSE will cause
GTK to emit the "destroy" signal which of course, calls the "destroy"
callback, exiting GTK.

Note that these signals are not the same as the Unix system signals,
and are not implemented using them, although the terminology is almost
792 793 794 795 796 797 798 799

<!-- ***************************************************************** -->
<sect>Moving On
<!-- ***************************************************************** -->

<!-- ----------------------------------------------------------------- -->
<sect1>Data Types
800 801 802 803
There are a few things you probably noticed in the previous examples
that need explaining. The gint, gchar etc. that you see are typedefs
to int and char respectively. This is done to get around that nasty
dependency on the size of simple data types when doing calculations.

805 806 807 808
A good example is "gint32" which will be typedef'd to a 32 bit integer
for any given platform, whether it be the 64 bit alpha, or the 32 bit
i386. The typedefs are very straight forward and intuitive. They are
all defined in glib/glib.h (which gets included from gtk.h).

810 811 812
You'll also notice the ability to use GtkWidget when the function
calls for a GtkObject. GTK is an object oriented design, and a widget
is an object.
813 814 815 816 817 818 819

<!-- ----------------------------------------------------------------- -->
<sect1>More on Signal Handlers
Lets take another look at the gtk_signal_connect declaration.

820 821 822 823
gint gtk_signal_connect( GtkObject *object,
                         gchar *name,
                         GtkSignalFunc func,
                         gpointer func_data );
824 825

826 827 828 829
Notice the gint return value? This is a tag that identifies your
callback function. As stated above, you may have as many callbacks per
signal and per object as you need, and each will be executed in turn,
in the order they were attached.

This tag allows you to remove this callback from the list by using:

834 835
void gtk_signal_disconnect( GtkObject *object,
                            gint id );

838 839
So, by passing in the widget you wish to remove the handler from, and
the tag returned by one of the signal_connect functions, you can
disconnect a signal handler.

Another function to remove all the signal handers from an object is:

void gtk_signal_handlers_destroy( GtkObject *object );

848 849 850
This call is fairly self explanatory. It simply removes all the
current signal handlers from the object passed in as the first
851 852 853 854

<!-- ----------------------------------------------------------------- -->
<sect1>An Upgraded Hello World
855 856 857
Let's take a look at a slightly improved <em>helloworld</em> with
better examples of callbacks. This will also introduce us to our next
topic, packing widgets.
858 859

/* example-start helloworld2 helloworld2.c */
861 862 863

#include <gtk/gtk.h>

864 865 866 867
/* Our new improved callback.  The data passed to this function
 * is printed to stdout. */
void callback( GtkWidget *widget,
               gpointer   data )
868 869 870 871 872
    g_print ("Hello again - %s was pressed\n", (char *) data);

/* another callback */
873 874 875
void delete_event( GtkWidget *widget,
                   GdkEvent  *event,
		   gpointer   data )
876 877 878 879
    gtk_main_quit ();

880 881
int main( int   argc,
          char *argv[] )
882 883 884 885 886 887
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;

888 889
    /* This is called in all GTK applications. Arguments are parsed
     * from the command line and are returned to the application. */
890 891
    gtk_init (&amp;argc, &amp;argv);

    /* Create a new window */
893 894
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    /* This is a new call, this just sets the title of our
896 897 898 899 900 901 902 903
     * new window to "Hello Buttons!" */
    gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");

    /* Here we just set a handler for delete_event that immediately
     * exits GTK. */
    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
			GTK_SIGNAL_FUNC (delete_event), NULL);

    /* Sets the border width of the window. */
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

907 908
    /* We create a box to pack widgets into.  This is described in detail
     * in the "packing" section. The box is not really visible, it
909 910 911
     * is just used as a tool to arrange widgets. */
    box1 = gtk_hbox_new(FALSE, 0);

    /* Put the box into the main window. */
913 914
    gtk_container_add (GTK_CONTAINER (window), box1);

    /* Creates a new button with the label "Button 1". */
916 917 918
    button = gtk_button_new_with_label ("Button 1");

    /* Now when the button is clicked, we call the "callback" function
     * with a pointer to "button 1" as its argument */
920 921 922
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");

    /* Instead of gtk_container_add, we pack this button into the invisible
924 925 926
     * box, which has been packed into the window. */
    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

927 928
    /* Always remember this step, this tells GTK that our preparation for
     * this button is complete, and it can now be displayed. */
929 930

    /* Do these same steps again to create a second button */
932 933
    button = gtk_button_new_with_label ("Button 2");

    /* Call the same callback function with a different argument,
935 936 937 938 939 940 941 942 943 944 945 946 947 948
     * passing a pointer to "button 2" instead. */
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
			GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");

    gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);

    /* The order in which we show the buttons is not really important, but I
     * recommend showing the window last, so it all pops up at once. */


    gtk_widget_show (window);

    /* Rest in gtk_main and wait for the fun to begin! */
950 951
    gtk_main ();

/* example-end */

957 958 959 960 961 962 963
Compile this program using the same linking arguments as our first
example.  You'll notice this time there is no easy way to exit the
program, you have to use your window manager or command line to kill
it. A good exercise for the reader would be to insert a third "Quit"
button that will exit the program. You may also wish to play with the
options to gtk_box_pack_start() while reading the next section.  Try
resizing the window, and observe the behavior.

965 966 967
Just as a side note, there is another useful define for
gtk_window_new() - GTK_WINDOW_DIALOG. This interacts with the window
manager a little differently and should be used for transient windows.
968 969 970 971 972

<!-- ***************************************************************** -->
<sect>Packing Widgets
<!-- ***************************************************************** -->
When creating an application, you'll want to put more than one widget
974 975 976 977 978
inside a window. Our first <em>helloworld</em> example only used one
widget so we could simply use a gtk_container_add call to "pack" the
widget into the window. But when you want to put more than one widget
into a window, how do you control where that widget is positioned?
This is where packing comes in.
979 980 981 982

<!-- ----------------------------------------------------------------- -->
<sect1>Theory of Packing Boxes
983 984 985 986 987 988 989 990 991 992 993
Most packing is done by creating boxes as in the example above. These
are invisible widget containers that we can pack our widgets into
which come in two forms, a horizontal box, and a vertical box. When
packing widgets into a horizontal box, the objects are inserted
horizontally from left to right or right to left depending on the call
used. In a vertical box, widgets are packed from top to bottom or vice
versa. You may use any combination of boxes inside or beside other
boxes to create the desired effect.

To create a new horizontal box, we use a call to gtk_hbox_new(), and
for vertical boxes, gtk_vbox_new().The gtk_box_pack_start() and
gtk_box_pack_end() functions are used to place objects inside of these
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
containers. The gtk_box_pack_start() function will start at the top
and work its way down in a vbox, and pack left to right in an hbox.
gtk_box_pack_end() will do the opposite, packing from bottom to top in
a vbox, and right to left in an hbox. Using these functions allow us
to right justify or left justify our widgets and may be mixed in any
way to achieve the desired effect. We will use gtk_box_pack_start() in
most of our examples. An object may be another container or a
widget. In fact, many widgets are actually containers themselves,
including the button, but we usually only use a label inside a button.

By using these calls, GTK knows where you want to place your widgets
so it can do automatic resizing and other nifty things. There's also a
number of options as to how your widgets should be packed. As you can
imagine, this method gives us a quite a bit of flexibility when
placing and creating widgets.
1010 1011 1012 1013 1014 1015

<!-- ----------------------------------------------------------------- -->
<sect1>Details of Boxes
Because of this flexibility, packing boxes in GTK can be confusing at
first. There are a lot of options, and it's not immediately obvious how
they all fit together. In the end however, there are basically five
different styles.
1018 1019 1020

<? <CENTER> >
1021 1022
<IMG SRC="gtk_tut_packbox1.gif" VSPACE="15" HSPACE="10" WIDTH="528"
HEIGHT="235" ALT="Box Packing Example Image">
1023 1024 1025 1026
<? </CENTER> >

Each line contains one horizontal box (hbox) with several buttons. The
1027 1028 1029
call to gtk_box_pack is shorthand for the call to pack each of the
buttons into the hbox. Each of the buttons is packed into the hbox the
same way (i.e. same arguments to the gtk_box_pack_start() function).

1031 1032 1033
This is the declaration of the gtk_box_pack_start function.

1034 1035 1036 1037 1038
void gtk_box_pack_start( GtkBox    *box,
                         GtkWidget *child,
                         gint       expand,
                         gint       fill,
                         gint       padding );
1039 1040

1041 1042 1043
The first argument is the box you are packing the object into, the
second is the object. The objects will all be buttons for now, so
we'll be packing buttons into boxes.

1045 1046 1047 1048 1049 1050 1051 1052
The expand argument to gtk_box_pack_start() and gtk_box_pack_end()
controls whether the widgets are laid out in the box to fill in all
the extra space in the box so the box is expanded to fill the area
alloted to it (TRUE).  Or the box is shrunk to just fit the widgets
(FALSE). Setting expand to FALSE will allow you to do right and left
justification of your widgets.  Otherwise, they will all expand to fit
into the box, and the same effect could be achieved by using only one
of gtk_box_pack_start or gtk_box_pack_end.

GMT 1998  Tony Gale's avatar