source: trunk/third/gtk/docs/html/gtk_tut-2.html @ 14482

Revision 14482, 25.3 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14481, which included commits to RCS files with non-trunk default branches.
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2<HTML>
3<HEAD>
4 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
5 <TITLE>GTK v1.2 Tutorial: Getting Started</TITLE>
6 <LINK HREF="gtk_tut-3.html" REL=next>
7 <LINK HREF="gtk_tut-1.html" REL=previous>
8 <LINK HREF="gtk_tut.html#toc2" REL=contents>
9</HEAD>
10<BODY BGCOLOR="#FFFFFF">
11<A HREF="gtk_tut-3.html">Next</A>
12<A HREF="gtk_tut-1.html">Previous</A>
13<A HREF="gtk_tut.html#toc2">Contents</A>
14<HR NOSHADE>
15<H2><A NAME="s2">2. Getting Started</A></H2>
16
17<P>The first thing to do, of course, is download the GTK source and
18install it. You can always get the latest version from ftp.gtk.org in
19/pub/gtk. You can also view other sources of GTK information on
20<A HREF="http://www.gtk.org/">http://www.gtk.org/</A>. GTK
21uses GNU autoconf for configuration. Once untar'd, type ./configure
22--help to see a list of options.
23<P>The GTK source distribution also contains the complete source to all
24of the examples used in this tutorial, along with Makefiles to aid
25compilation.
26<P>To begin our introduction to GTK, we'll start with the simplest
27program possible. This program will create a 200x200 pixel window and
28has no way of exiting except to be killed by using the shell.
29<P>
30<BLOCKQUOTE><CODE>
31<PRE>
32/* example-start base base.c */
33
34#include &lt;gtk/gtk.h>
35
36int main( int   argc,
37          char *argv[] )
38{
39    GtkWidget *window;
40   
41    gtk_init (&amp;argc, &amp;argv);
42   
43    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
44    gtk_widget_show  (window);
45   
46    gtk_main ();
47   
48    return(0);
49}
50/* example-end */
51</PRE>
52</CODE></BLOCKQUOTE>
53<P>You can compile the above program with gcc using:
54<BLOCKQUOTE><CODE>
55<PRE>
56gcc base.c -o base `gtk-config --cflags --libs`
57</PRE>
58</CODE></BLOCKQUOTE>
59<P>The meaning of the unusual compilation options is explained below in
60<A HREF="#sec_compiling">Compiling Hello World</A>.
61<P>All programs will of course include gtk/gtk.h which declares the
62variables, functions, structures, etc. that will be used in your GTK
63application.
64<P>The next line:
65<P>
66<BLOCKQUOTE><CODE>
67<PRE>
68gtk_init (&amp;argc, &amp;argv);
69</PRE>
70</CODE></BLOCKQUOTE>
71<P>calls the function gtk_init(gint *argc, gchar ***argv) which will be
72called in all GTK applications. This sets up a few things for us such
73as the default visual and color map and then proceeds to call
74gdk_init(gint *argc, gchar ***argv). This function initializes the
75library for use, sets up default signal handlers, and checks the
76arguments passed to your application on the command line, looking for
77one of the following:
78<P>
79<UL>
80<LI> <CODE>--gtk-module</CODE></LI>
81<LI> <CODE>--g-fatal-warnings</CODE></LI>
82<LI> <CODE>--gtk-debug</CODE></LI>
83<LI> <CODE>--gtk-no-debug</CODE></LI>
84<LI> <CODE>--gdk-debug</CODE></LI>
85<LI> <CODE>--gdk-no-debug</CODE></LI>
86<LI> <CODE>--display</CODE></LI>
87<LI> <CODE>--sync</CODE></LI>
88<LI> <CODE>--no-xshm</CODE></LI>
89<LI> <CODE>--name</CODE></LI>
90<LI> <CODE>--class</CODE></LI>
91</UL>
92<P>It removes these from the argument list, leaving anything it does not
93recognize for your application to parse or ignore. This creates a set
94of standard arguments accepted by all GTK applications.
95<P>The next two lines of code create and display a window.
96<P>
97<BLOCKQUOTE><CODE>
98<PRE>
99  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
100  gtk_widget_show (window);
101</PRE>
102</CODE></BLOCKQUOTE>
103<P>The <CODE>GTK_WINDOW_TOPLEVEL</CODE> argument specifies that we want the
104window to undergo window manager decoration and placement. Rather than
105create a window of 0x0 size, a window without children is set to
106200x200 by default so you can still manipulate it.
107<P>The gtk_widget_show() function lets GTK know that we are done setting
108the attributes of this widget, and that it can display it.
109<P>The last line enters the GTK main processing loop.
110<P>
111<BLOCKQUOTE><CODE>
112<PRE>
113  gtk_main ();
114</PRE>
115</CODE></BLOCKQUOTE>
116<P>gtk_main() is another call you will see in every GTK application.
117When control reaches this point, GTK will sleep waiting for X events
118(such as button or key presses), timeouts, or file IO notifications to
119occur. In our simple example, however, events are ignored.
120<P>
121<H2><A NAME="ss2.1">2.1 Hello World in GTK</A>
122</H2>
123
124<P>Now for a program with a widget (a button).  It's the classic
125hello world a la GTK.
126<P>
127<BLOCKQUOTE><CODE>
128<PRE>
129/* example-start helloworld helloworld.c */
130
131#include &lt;gtk/gtk.h>
132
133/* This is a callback function. The data arguments are ignored
134 * in this example. More on callbacks below. */
135void hello( GtkWidget *widget,
136            gpointer   data )
137{
138    g_print ("Hello World\n");
139}
140
141gint delete_event( GtkWidget *widget,
142                   GdkEvent  *event,
143                   gpointer   data )
144{
145    /* If you return FALSE in the "delete_event" signal handler,
146     * GTK will emit the "destroy" signal. Returning TRUE means
147     * you don't want the window to be destroyed.
148     * This is useful for popping up 'are you sure you want to quit?'
149     * type dialogs. */
150
151    g_print ("delete event occurred\n");
152
153    /* Change TRUE to FALSE and the main window will be destroyed with
154     * a "delete_event". */
155
156    return(TRUE);
157}
158
159/* Another callback */
160void destroy( GtkWidget *widget,
161              gpointer   data )
162{
163    gtk_main_quit();
164}
165
166int main( int   argc,
167          char *argv[] )
168{
169    /* GtkWidget is the storage type for widgets */
170    GtkWidget *window;
171    GtkWidget *button;
172   
173    /* This is called in all GTK applications. Arguments are parsed
174     * from the command line and are returned to the application. */
175    gtk_init(&amp;argc, &amp;argv);
176   
177    /* create a new window */
178    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
179   
180    /* When the window is given the "delete_event" signal (this is given
181     * by the window manager, usually by the "close" option, or on the
182     * titlebar), we ask it to call the delete_event () function
183     * as defined above. The data passed to the callback
184     * function is NULL and is ignored in the callback function. */
185    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
186                        GTK_SIGNAL_FUNC (delete_event), NULL);
187   
188    /* Here we connect the "destroy" event to a signal handler. 
189     * This event occurs when we call gtk_widget_destroy() on the window,
190     * or if we return FALSE in the "delete_event" callback. */
191    gtk_signal_connect (GTK_OBJECT (window), "destroy",
192                        GTK_SIGNAL_FUNC (destroy), NULL);
193   
194    /* Sets the border width of the window. */
195    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
196   
197    /* Creates a new button with the label "Hello World". */
198    button = gtk_button_new_with_label ("Hello World");
199   
200    /* When the button receives the "clicked" signal, it will call the
201     * function hello() passing it NULL as its argument.  The hello()
202     * function is defined above. */
203    gtk_signal_connect (GTK_OBJECT (button), "clicked",
204                        GTK_SIGNAL_FUNC (hello), NULL);
205   
206    /* This will cause the window to be destroyed by calling
207     * gtk_widget_destroy(window) when "clicked".  Again, the destroy
208     * signal could come from here, or the window manager. */
209    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
210                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
211                               GTK_OBJECT (window));
212   
213    /* This packs the button into the window (a gtk container). */
214    gtk_container_add (GTK_CONTAINER (window), button);
215   
216    /* The final step is to display this newly created widget. */
217    gtk_widget_show (button);
218   
219    /* and the window */
220    gtk_widget_show (window);
221   
222    /* All GTK applications must have a gtk_main(). Control ends here
223     * and waits for an event to occur (like a key press or
224     * mouse event). */
225    gtk_main ();
226   
227    return(0);
228}
229/* example-end */
230</PRE>
231</CODE></BLOCKQUOTE>
232<P>
233<H2><A NAME="sec_compiling"></A> <A NAME="ss2.2">2.2 Compiling Hello World </A>
234</H2>
235
236<P>To compile use:
237<P>
238<BLOCKQUOTE><CODE>
239<PRE>
240gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \
241    `gtk-config --libs`
242</PRE>
243</CODE></BLOCKQUOTE>
244<P>This uses the program <CODE>gtk-config</CODE>, which comes with GTK. This
245program "knows" what compiler switches are needed to compile programs
246that use GTK. <CODE>gtk-config --cflags</CODE> will output a list of include
247directories for the compiler to look in, and <CODE>gtk-config --libs</CODE>
248will output the list of libraries for the compiler to link with and
249the directories to find them in. In the above example they could have
250been combined into a single instance, such as
251<CODE>`gtk-config --cflags --libs`</CODE>.
252<P>Note that the type of single quote used in the compile command above
253is significant.
254<P>The libraries that are usually linked in are:
255<UL>
256<LI>The GTK library (-lgtk), the widget library, based on top of GDK.</LI>
257<LI>The GDK library (-lgdk), the Xlib wrapper.</LI>
258<LI>The gmodule library (-lgmodule), which is used to load run time
259extensions.</LI>
260<LI>The GLib library (-lglib), containing miscellaneous functions;
261only g_print() is used in this particular example. GTK is built on top
262of glib so you will always require this library. See the section on
263<A HREF="gtk_tut-20.html#sec_glib">GLib</A> for details.</LI>
264<LI>The Xlib library (-lX11) which is used by GDK.</LI>
265<LI>The Xext library (-lXext). This contains code for shared memory
266pixmaps and other X extensions.</LI>
267<LI>The math library (-lm). This is used by GTK for various purposes.</LI>
268</UL>
269<P>
270<H2><A NAME="ss2.3">2.3 Theory of Signals and Callbacks</A>
271</H2>
272
273<P>Before we look in detail at <EM>helloworld</EM>, we'll discuss signals
274and callbacks. GTK is an event driven toolkit, which means it will
275sleep in gtk_main until an event occurs and control is passed to the
276appropriate function.
277<P>This passing of control is done using the idea of "signals". (Note
278that these signals are not the same as the Unix system signals, and
279are not implemented using them, although the terminology is almost
280identical.) When an event occurs, such as the press of a mouse button,
281the appropriate signal will be "emitted" by the widget that was
282pressed.  This is how GTK does most of its useful work. There are
283signals that all widgets inherit, such as "destroy", and there are
284signals that are widget specific, such as "toggled" on a toggle
285button.
286<P>To make a button perform an action, we set up a signal handler to
287catch these signals and call the appropriate function. This is done by
288using a function such as:
289<P>
290<BLOCKQUOTE><CODE>
291<PRE>
292gint gtk_signal_connect( GtkObject     *object,
293                         gchar         *name,
294                         GtkSignalFunc  func,
295                         gpointer       func_data );
296</PRE>
297</CODE></BLOCKQUOTE>
298<P>where the first argument is the widget which will be emitting the
299signal, and the second the name of the signal you wish to catch. The
300third is the function you wish to be called when it is caught, and the
301fourth, the data you wish to have passed to this function.
302<P>The function specified in the third argument is called a "callback
303function", and should generally be of the form
304<P>
305<BLOCKQUOTE><CODE>
306<PRE>
307void callback_func( GtkWidget *widget,
308                    gpointer   callback_data );
309</PRE>
310</CODE></BLOCKQUOTE>
311<P>where the first argument will be a pointer to the widget that emitted
312the signal, and the second a pointer to the data given as the last
313argument to the gtk_signal_connect() function as shown above.
314<P>Note that the above form for a signal callback function declaration is
315only a general guide, as some widget specific signals generate
316different calling parameters. For example, the CList "select_row"
317signal provides both row and column parameters.
318<P>Another call used in the <EM>helloworld</EM> example, is:
319<P>
320<BLOCKQUOTE><CODE>
321<PRE>
322gint gtk_signal_connect_object( GtkObject     *object,
323                                gchar         *name,
324                                GtkSignalFunc  func,
325                                GtkObject     *slot_object );
326</PRE>
327</CODE></BLOCKQUOTE>
328<P>gtk_signal_connect_object() is the same as gtk_signal_connect() except
329that the callback function only uses one argument, a pointer to a GTK
330object. So when using this function to connect signals, the callback
331should be of the form
332<P>
333<BLOCKQUOTE><CODE>
334<PRE>
335void callback_func( GtkObject *object );
336</PRE>
337</CODE></BLOCKQUOTE>
338<P>where the object is usually a widget. We usually don't setup callbacks
339for gtk_signal_connect_object however. They are usually used to call a
340GTK function that accepts a single widget or object as an argument, as
341is the case in our <EM>helloworld</EM> example.
342<P>The purpose of having two functions to connect signals is simply to
343allow the callbacks to have a different number of arguments. Many
344functions in the GTK library accept only a single GtkWidget pointer as
345an argument, so you want to use the gtk_signal_connect_object() for
346these, whereas for your functions, you may need to have additional
347data supplied to the callbacks.
348<P>
349<H2><A NAME="ss2.4">2.4 Events</A>
350</H2>
351
352<P>In addition to the signal mechanism described above, there is a set
353of <EM>events</EM> that reflect the X event mechanism. Callbacks may
354also be attached to these events. These events are:
355<P>
356<UL>
357<LI> event</LI>
358<LI> button_press_event</LI>
359<LI> button_release_event</LI>
360<LI> motion_notify_event</LI>
361<LI> delete_event</LI>
362<LI> destroy_event</LI>
363<LI> expose_event</LI>
364<LI> key_press_event</LI>
365<LI> key_release_event</LI>
366<LI> enter_notify_event</LI>
367<LI> leave_notify_event</LI>
368<LI> configure_event</LI>
369<LI> focus_in_event</LI>
370<LI> focus_out_event</LI>
371<LI> map_event</LI>
372<LI> unmap_event</LI>
373<LI> property_notify_event</LI>
374<LI> selection_clear_event</LI>
375<LI> selection_request_event</LI>
376<LI> selection_notify_event</LI>
377<LI> proximity_in_event</LI>
378<LI> proximity_out_event</LI>
379<LI> drag_begin_event</LI>
380<LI> drag_request_event</LI>
381<LI> drag_end_event</LI>
382<LI> drop_enter_event</LI>
383<LI> drop_leave_event</LI>
384<LI> drop_data_available_event</LI>
385<LI> other_event</LI>
386</UL>
387<P>In order to connect a callback function to one of these events, you
388use the function gtk_signal_connect, as described above, using one of
389the above event names as the <CODE>name</CODE> parameter. The callback
390function for events has a slightly different form than that for
391signals:
392<P>
393<BLOCKQUOTE><CODE>
394<PRE>
395void callback_func( GtkWidget *widget,
396                    GdkEvent  *event,
397                    gpointer   callback_data );
398</PRE>
399</CODE></BLOCKQUOTE>
400<P>GdkEvent is a C <CODE>union</CODE> structure whose type will depend upon which
401of the above events has occurred. In order for us to tell which event
402has been issued each of the possible alternatives has a <CODE>type</CODE>
403parameter which reflects the event being issued. The other components
404of the event structure will depend upon the type of the
405event. Possible values for the type are:
406<P>
407<BLOCKQUOTE><CODE>
408<PRE>
409  GDK_NOTHING
410  GDK_DELETE
411  GDK_DESTROY
412  GDK_EXPOSE
413  GDK_MOTION_NOTIFY
414  GDK_BUTTON_PRESS
415  GDK_2BUTTON_PRESS
416  GDK_3BUTTON_PRESS
417  GDK_BUTTON_RELEASE
418  GDK_KEY_PRESS
419  GDK_KEY_RELEASE
420  GDK_ENTER_NOTIFY
421  GDK_LEAVE_NOTIFY
422  GDK_FOCUS_CHANGE
423  GDK_CONFIGURE
424  GDK_MAP
425  GDK_UNMAP
426  GDK_PROPERTY_NOTIFY
427  GDK_SELECTION_CLEAR
428  GDK_SELECTION_REQUEST
429  GDK_SELECTION_NOTIFY
430  GDK_PROXIMITY_IN
431  GDK_PROXIMITY_OUT
432  GDK_DRAG_BEGIN
433  GDK_DRAG_REQUEST
434  GDK_DROP_ENTER
435  GDK_DROP_LEAVE
436  GDK_DROP_DATA_AVAIL
437  GDK_CLIENT_EVENT
438  GDK_VISIBILITY_NOTIFY
439  GDK_NO_EXPOSE
440  GDK_OTHER_EVENT       /* Deprecated, use filters instead */
441</PRE>
442</CODE></BLOCKQUOTE>
443<P>So, to connect a callback function to one of these events we would use
444something like:
445<P>
446<BLOCKQUOTE><CODE>
447<PRE>
448gtk_signal_connect( GTK_OBJECT(button), "button_press_event",
449                    GTK_SIGNAL_FUNC(button_press_callback),
450                    NULL);
451</PRE>
452</CODE></BLOCKQUOTE>
453<P>This assumes that <CODE>button</CODE> is a Button widget. Now, when the
454mouse is over the button and a mouse button is pressed, the function
455<CODE>button_press_callback</CODE> will be called. This function may be
456declared as:
457<P>
458<BLOCKQUOTE><CODE>
459<PRE>
460static gint button_press_callback( GtkWidget      *widget,
461                                   GdkEventButton *event,
462                                   gpointer        data );
463</PRE>
464</CODE></BLOCKQUOTE>
465<P>Note that we can declare the second argument as type
466<CODE>GdkEventButton</CODE> as we know what type of event will occur for this
467function to be called.
468<P>The value returned from this function indicates whether the event
469should be propagated further by the GTK event handling
470mechanism. Returning TRUE indicates that the event has been handled,
471and that it should not propagate further. Returning FALSE continues
472the normal event handling.  See the section on
473<A HREF="gtk_tut-18.html#sec_Adv_Events_and_Signals">Advanced Event and Signal Handling</A> for more details on this
474propagation process.
475<P>For details on the GdkEvent data types, see the appendix entitled
476<A HREF="gtk_tut-29.html#sec_GDK_Event_Types">GDK Event Types</A>.
477<P>
478<H2><A NAME="ss2.5">2.5 Stepping Through Hello World</A>
479</H2>
480
481<P>Now that we know the theory behind this, let's clarify by walking
482through the example <EM>helloworld</EM> program.
483<P>Here is the callback function that will be called when the button is
484"clicked". We ignore both the widget and the data in this example, but
485it is not hard to do things with them. The next example will use the
486data argument to tell us which button was pressed.
487<P>
488<BLOCKQUOTE><CODE>
489<PRE>
490void hello( GtkWidget *widget,
491            gpointer   data )
492{
493    g_print ("Hello World\n");
494}
495</PRE>
496</CODE></BLOCKQUOTE>
497<P>The next callback is a bit special. The "delete_event" occurs when the
498window manager sends this event to the application. We have a choice
499here as to what to do about these events. We can ignore them, make
500some sort of response, or simply quit the application.
501<P>The value you return in this callback lets GTK know what action to
502take.  By returning TRUE, we let it know that we don't want to have
503the "destroy" signal emitted, keeping our application running. By
504returning FALSE, we ask that "destroy" be emitted, which in turn will
505call our "destroy" signal handler.
506<P>
507<BLOCKQUOTE><CODE>
508<PRE>
509gint delete_event( GtkWidget *widget,
510                   GdkEvent  *event,
511                   gpointer   data )
512{
513    g_print ("delete event occurred\n");
514
515    return (TRUE);
516}
517</PRE>
518</CODE></BLOCKQUOTE>
519<P>Here is another callback function which causes the program to quit by
520calling gtk_main_quit(). This function tells GTK that it is to exit
521from gtk_main when control is returned to it.
522<P>
523<BLOCKQUOTE><CODE>
524<PRE>
525void destroy( GtkWidget *widget,
526              gpointer   data )
527{
528    gtk_main_quit ();
529}
530</PRE>
531</CODE></BLOCKQUOTE>
532<P>I assume you know about the main() function... yes, as with other
533applications, all GTK applications will also have one of these.
534<P>
535<BLOCKQUOTE><CODE>
536<PRE>
537int main( int   argc,
538          char *argv[] )
539{
540</PRE>
541</CODE></BLOCKQUOTE>
542<P>This next part declares pointers to a structure of type
543GtkWidget. These are used below to create a window and a button.
544<P>
545<BLOCKQUOTE><CODE>
546<PRE>
547    GtkWidget *window;
548    GtkWidget *button;
549</PRE>
550</CODE></BLOCKQUOTE>
551<P>Here is our gtk_init again. As before, this initializes the toolkit,
552and parses the arguments found on the command line. Any argument it
553recognizes from the command line, it removes from the list, and
554modifies argc and argv to make it look like they never existed,
555allowing your application to parse the remaining arguments.
556<P>
557<BLOCKQUOTE><CODE>
558<PRE>
559    gtk_init (&amp;argc, &amp;argv);
560</PRE>
561</CODE></BLOCKQUOTE>
562<P>Create a new window. This is fairly straightforward. Memory is
563allocated for the GtkWidget *window structure so it now points to a
564valid structure. It sets up a new window, but it is not displayed
565until we call gtk_widget_show(window) near the end of our program.
566<P>
567<BLOCKQUOTE><CODE>
568<PRE>
569    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
570</PRE>
571</CODE></BLOCKQUOTE>
572<P>Here are two examples of connecting a signal handler to an object, in
573this case, the window. Here, the "delete_event" and "destroy" signals
574are caught. The first is emitted when we use the window manager to
575kill the window, or when we use the gtk_widget_destroy() call passing
576in the window widget as the object to destroy. The second is emitted
577when, in the "delete_event" handler, we return FALSE.
578<P>The <CODE>GTK_OBJECT</CODE> and <CODE>GTK_SIGNAL_FUNC</CODE> are macros that perform
579type casting and checking for us, as well as aid the readability of
580the code.
581<P>
582<BLOCKQUOTE><CODE>
583<PRE>
584    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
585                        GTK_SIGNAL_FUNC (delete_event), NULL);
586    gtk_signal_connect (GTK_OBJECT (window), "destroy",
587                        GTK_SIGNAL_FUNC (destroy), NULL);
588</PRE>
589</CODE></BLOCKQUOTE>
590<P>This next function is used to set an attribute of a container object.
591This just sets the window so it has a blank area along the inside of
592it 10 pixels wide where no widgets will go. There are other similar
593functions which we will look at in the section on
594<A HREF="gtk_tut-16.html#sec_setting_widget_attributes">Setting Widget Attributes</A><P>And again, <CODE>GTK_CONTAINER</CODE> is a macro to perform type casting.
595<P>
596<BLOCKQUOTE><CODE>
597<PRE>
598    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
599</PRE>
600</CODE></BLOCKQUOTE>
601<P>This call creates a new button. It allocates space for a new GtkWidget
602structure in memory, initializes it, and makes the button pointer
603point to it. It will have the label "Hello World" on it when
604displayed.
605<P>
606<BLOCKQUOTE><CODE>
607<PRE>
608    button = gtk_button_new_with_label ("Hello World");
609</PRE>
610</CODE></BLOCKQUOTE>
611<P>Here, we take this button, and make it do something useful. We attach
612a signal handler to it so when it emits the "clicked" signal, our
613hello() function is called. The data is ignored, so we simply pass in
614NULL to the hello() callback function. Obviously, the "clicked" signal
615is emitted when we click the button with our mouse pointer.
616<P>
617<BLOCKQUOTE><CODE>
618<PRE>
619    gtk_signal_connect (GTK_OBJECT (button), "clicked",
620                        GTK_SIGNAL_FUNC (hello), NULL);
621</PRE>
622</CODE></BLOCKQUOTE>
623<P>We are also going to use this button to exit our program. This will
624illustrate how the "destroy" signal may come from either the window
625manager, or our program. When the button is "clicked", same as above,
626it calls the first hello() callback function, and then this one in the
627order they are set up. You may have as many callback functions as you
628need, and all will be executed in the order you connected
629them. Because the gtk_widget_destroy() function accepts only a
630GtkWidget *widget as an argument, we use the
631gtk_signal_connect_object() function here instead of straight
632gtk_signal_connect().
633<P>
634<BLOCKQUOTE><CODE>
635<PRE>
636    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
637                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
638                               GTK_OBJECT (window));
639</PRE>
640</CODE></BLOCKQUOTE>
641<P>This is a packing call, which will be explained in depth later on in
642<A HREF="gtk_tut-4.html#sec_packing_widgets">Packing Widgets</A>. But it is
643fairly easy to understand. It simply tells GTK that the button is to
644be placed in the window where it will be displayed. Note that a GTK
645container can only contain one widget. There are other widgets, that
646are described later, which are designed to layout multiple widgets in
647various ways.
648<P>
649<BLOCKQUOTE><CODE>
650<PRE>
651    gtk_container_add (GTK_CONTAINER (window), button);
652</PRE>
653</CODE></BLOCKQUOTE>
654<P>Now we have everything set up the way we want it to be. With all the
655signal handlers in place, and the button placed in the window where it
656should be, we ask GTK to "show" the widgets on the screen. The window
657widget is shown last so the whole window will pop up at once rather
658than seeing the window pop up, and then the button form inside of
659it. Although with such a simple example, you'd never notice.
660<P>
661<BLOCKQUOTE><CODE>
662<PRE>
663    gtk_widget_show (button);
664
665    gtk_widget_show (window);
666</PRE>
667</CODE></BLOCKQUOTE>
668<P>And of course, we call gtk_main() which waits for events to come from
669the X server and will call on the widgets to emit signals when these
670events come.
671<P>
672<BLOCKQUOTE><CODE>
673<PRE>
674    gtk_main ();
675</PRE>
676</CODE></BLOCKQUOTE>
677<P>And the final return. Control returns here after gtk_quit() is called.
678<P>
679<BLOCKQUOTE><CODE>
680<PRE>
681    return (0);
682</PRE>
683</CODE></BLOCKQUOTE>
684<P>Now, when we click the mouse button on a GTK button, the widget emits
685a "clicked" signal. In order for us to use this information, our
686program sets up a signal handler to catch that signal, which
687dispatches the function of our choice. In our example, when the button
688we created is "clicked", the hello() function is called with a NULL
689argument, and then the next handler for this signal is called. This
690calls the gtk_widget_destroy() function, passing it the window widget
691as its argument, destroying the window widget. This causes the window
692to emit the "destroy" signal, which is caught, and calls our destroy()
693callback function, which simply exits GTK.
694<P>Another course of events is to use the window manager to kill the
695window, which will cause the "delete_event" to be emitted. This will
696call our "delete_event" handler. If we return TRUE here, the window
697will be left as is and nothing will happen. Returning FALSE will cause
698GTK to emit the "destroy" signal which of course calls the "destroy"
699callback, exiting GTK.
700<P>
701<HR NOSHADE>
702<A HREF="gtk_tut-3.html">Next</A>
703<A HREF="gtk_tut-1.html">Previous</A>
704<A HREF="gtk_tut.html#toc2">Contents</A>
705</BODY>
706</HTML>
Note: See TracBrowser for help on using the repository browser.