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

Revision 14482, 25.4 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: Packing Widgets </TITLE>
6 <LINK HREF="gtk_tut-5.html" REL=next>
7 <LINK HREF="gtk_tut-3.html" REL=previous>
8 <LINK HREF="gtk_tut.html#toc4" REL=contents>
9</HEAD>
10<BODY BGCOLOR="#FFFFFF">
11<A HREF="gtk_tut-5.html">Next</A>
12<A HREF="gtk_tut-3.html">Previous</A>
13<A HREF="gtk_tut.html#toc4">Contents</A>
14<HR NOSHADE>
15<H2><A NAME="sec_packing_widgets"></A> <A NAME="s4">4. Packing Widgets </A></H2>
16
17<P>When creating an application, you'll want to put more than one widget
18inside a window. Our first <EM>helloworld</EM> example only used one
19widget so we could simply use a gtk_container_add call to "pack" the
20widget into the window. But when you want to put more than one widget
21into a window, how do you control where that widget is positioned?
22This is where packing comes in.
23<P>
24<H2><A NAME="ss4.1">4.1 Theory of Packing Boxes</A>
25</H2>
26
27<P>Most packing is done by creating boxes as in the example above. These
28are invisible widget containers that we can pack our widgets into
29which come in two forms, a horizontal box, and a vertical box. When
30packing widgets into a horizontal box, the objects are inserted
31horizontally from left to right or right to left depending on the call
32used. In a vertical box, widgets are packed from top to bottom or vice
33versa. You may use any combination of boxes inside or beside other
34boxes to create the desired effect.
35<P>To create a new horizontal box, we use a call to gtk_hbox_new(), and
36for vertical boxes, gtk_vbox_new(). The gtk_box_pack_start() and
37gtk_box_pack_end() functions are used to place objects inside of these
38containers. The gtk_box_pack_start() function will start at the top
39and work its way down in a vbox, and pack left to right in an hbox.
40gtk_box_pack_end() will do the opposite, packing from bottom to top in
41a vbox, and right to left in an hbox. Using these functions allows us
42to right justify or left justify our widgets and may be mixed in any
43way to achieve the desired effect. We will use gtk_box_pack_start() in
44most of our examples. An object may be another container or a
45widget. In fact, many widgets are actually containers themselves,
46including the button, but we usually only use a label inside a button.
47<P>By using these calls, GTK knows where you want to place your widgets
48so it can do automatic resizing and other nifty things. There are also
49a number of options as to how your widgets should be packed. As you
50can imagine, this method gives us a quite a bit of flexibility when
51placing and creating widgets.
52<P>
53<H2><A NAME="ss4.2">4.2 Details of Boxes</A>
54</H2>
55
56<P>Because of this flexibility, packing boxes in GTK can be confusing at
57first. There are a lot of options, and it's not immediately obvious how
58they all fit together. In the end, however, there are basically five
59different styles.
60<P> <CENTER >
61<IMG SRC="gtk_tut_packbox1.gif" VSPACE="15" HSPACE="10" WIDTH="528"
62HEIGHT="235" ALT="Box Packing Example Image"
63> </CENTER
64 >
65<P>Each line contains one horizontal box (hbox) with several buttons. The
66call to gtk_box_pack is shorthand for the call to pack each of the
67buttons into the hbox. Each of the buttons is packed into the hbox the
68same way (i.e., same arguments to the gtk_box_pack_start() function).
69<P>This is the declaration of the gtk_box_pack_start function.
70<P>
71<BLOCKQUOTE><CODE>
72<PRE>
73void gtk_box_pack_start( GtkBox    *box,
74                         GtkWidget *child,
75                         gint       expand,
76                         gint       fill,
77                         gint       padding );
78</PRE>
79</CODE></BLOCKQUOTE>
80<P>The first argument is the box you are packing the object into, the
81second is the object. The objects will all be buttons for now, so
82we'll be packing buttons into boxes.
83<P>The expand argument to gtk_box_pack_start() and gtk_box_pack_end()
84controls whether the widgets are laid out in the box to fill in all
85the extra space in the box so the box is expanded to fill the area
86allotted to it (TRUE); or the box is shrunk to just fit the widgets
87(FALSE). Setting expand to FALSE will allow you to do right and left
88justification of your widgets.  Otherwise, they will all expand to fit
89into the box, and the same effect could be achieved by using only one
90of gtk_box_pack_start or gtk_box_pack_end.
91<P>The fill argument to the gtk_box_pack functions control whether the
92extra space is allocated to the objects themselves (TRUE), or as extra
93padding in the box around these objects (FALSE). It only has an effect
94if the expand argument is also TRUE.
95<P>When creating a new box, the function looks like this:
96<P>
97<BLOCKQUOTE><CODE>
98<PRE>
99GtkWidget *gtk_hbox_new (gint homogeneous,
100                         gint spacing);
101</PRE>
102</CODE></BLOCKQUOTE>
103<P>The homogeneous argument to gtk_hbox_new (and the same for
104gtk_vbox_new) controls whether each object in the box has the same
105size (i.e., the same width in an hbox, or the same height in a
106vbox). If it is set, the gtk_box_pack routines function essentially
107as if the <CODE>expand</CODE> argument was always turned on.
108<P>What's the difference between spacing (set when the box is created)
109and padding (set when elements are packed)? Spacing is added between
110objects, and padding is added on either side of an object. The
111following figure should make it clearer:
112<P> <CENTER >
113<IMG ALIGN="center" SRC="gtk_tut_packbox2.gif" WIDTH="509"
114HEIGHT="213" VSPACE="15" HSPACE="10"
115ALT="Box Packing Example Image"
116> </CENTER
117 >
118<P>Here is the code used to create the above images. I've commented it
119fairly heavily so I hope you won't have any problems following
120it. Compile it yourself and play with it.
121<P>
122<H2><A NAME="ss4.3">4.3 Packing Demonstration Program</A>
123</H2>
124
125<P>
126<BLOCKQUOTE><CODE>
127<PRE>
128/* example-start packbox packbox.c */
129
130#include &lt;stdio.h>
131#include &lt;stdlib.h>
132#include "gtk/gtk.h"
133
134gint delete_event( GtkWidget *widget,
135                   GdkEvent  *event,
136                   gpointer   data )
137{
138    gtk_main_quit();
139    return(FALSE);
140}
141
142/* Make a new hbox filled with button-labels. Arguments for the
143 * variables we're interested are passed in to this function.
144 * We do not show the box, but do show everything inside. */
145GtkWidget *make_box( gint homogeneous,
146                     gint spacing,
147                     gint expand,
148                     gint fill,
149                     gint padding )
150{
151    GtkWidget *box;
152    GtkWidget *button;
153    char padstr[80];
154   
155    /* Create a new hbox with the appropriate homogeneous
156     * and spacing settings */
157    box = gtk_hbox_new (homogeneous, spacing);
158   
159    /* Create a series of buttons with the appropriate settings */
160    button = gtk_button_new_with_label ("gtk_box_pack");
161    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
162    gtk_widget_show (button);
163   
164    button = gtk_button_new_with_label ("(box,");
165    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
166    gtk_widget_show (button);
167   
168    button = gtk_button_new_with_label ("button,");
169    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
170    gtk_widget_show (button);
171   
172    /* Create a button with the label depending on the value of
173     * expand. */
174    if (expand == TRUE)
175            button = gtk_button_new_with_label ("TRUE,");
176    else
177            button = gtk_button_new_with_label ("FALSE,");
178   
179    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
180    gtk_widget_show (button);
181   
182    /* This is the same as the button creation for "expand"
183     * above, but uses the shorthand form. */
184    button = gtk_button_new_with_label (fill ? "TRUE," : "FALSE,");
185    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
186    gtk_widget_show (button);
187   
188    sprintf (padstr, "%d);", padding);
189   
190    button = gtk_button_new_with_label (padstr);
191    gtk_box_pack_start (GTK_BOX (box), button, expand, fill, padding);
192    gtk_widget_show (button);
193   
194    return box;
195}
196
197int main( int   argc,
198          char *argv[])
199{
200    GtkWidget *window;
201    GtkWidget *button;
202    GtkWidget *box1;
203    GtkWidget *box2;
204    GtkWidget *separator;
205    GtkWidget *label;
206    GtkWidget *quitbox;
207    int which;
208   
209    /* Our init, don't forget this! :) */
210    gtk_init (&amp;argc, &amp;argv);
211   
212    if (argc != 2) {
213        fprintf (stderr, "usage: packbox num, where num is 1, 2, or 3.\n");
214        /* This just does cleanup in GTK and exits with an exit status of 1. */
215        gtk_exit (1);
216    }
217   
218    which = atoi (argv[1]);
219
220    /* Create our window */
221    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
222
223    /* You should always remember to connect the delete_event signal
224     * to the main window. This is very important for proper intuitive
225     * behavior */
226    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
227                        GTK_SIGNAL_FUNC (delete_event), NULL);
228    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
229   
230    /* We create a vertical box (vbox) to pack the horizontal boxes into.
231     * This allows us to stack the horizontal boxes filled with buttons one
232     * on top of the other in this vbox. */
233    box1 = gtk_vbox_new (FALSE, 0);
234   
235    /* which example to show. These correspond to the pictures above. */
236    switch (which) {
237    case 1:
238        /* create a new label. */
239        label = gtk_label_new ("gtk_hbox_new (FALSE, 0);");
240       
241        /* Align the label to the left side.  We'll discuss this function and
242         * others in the section on Widget Attributes. */
243        gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
244
245        /* Pack the label into the vertical box (vbox box1).  Remember that
246         * widgets added to a vbox will be packed one on top of the other in
247         * order. */
248        gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
249       
250        /* Show the label */
251        gtk_widget_show (label);
252       
253        /* Call our make box function - homogeneous = FALSE, spacing = 0,
254         * expand = FALSE, fill = FALSE, padding = 0 */
255        box2 = make_box (FALSE, 0, FALSE, FALSE, 0);
256        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
257        gtk_widget_show (box2);
258
259        /* Call our make box function - homogeneous = FALSE, spacing = 0,
260         * expand = TRUE, fill = FALSE, padding = 0 */
261        box2 = make_box (FALSE, 0, TRUE, FALSE, 0);
262        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
263        gtk_widget_show (box2);
264       
265        /* Args are: homogeneous, spacing, expand, fill, padding */
266        box2 = make_box (FALSE, 0, TRUE, TRUE, 0);
267        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
268        gtk_widget_show (box2);
269       
270        /* Creates a separator, we'll learn more about these later,
271         * but they are quite simple. */
272        separator = gtk_hseparator_new ();
273       
274        /* Pack the separator into the vbox. Remember each of these
275         * widgets is being packed into a vbox, so they'll be stacked
276         * vertically. */
277        gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
278        gtk_widget_show (separator);
279       
280        /* Create another new label, and show it. */
281        label = gtk_label_new ("gtk_hbox_new (TRUE, 0);");
282        gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
283        gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
284        gtk_widget_show (label);
285       
286        /* Args are: homogeneous, spacing, expand, fill, padding */
287        box2 = make_box (TRUE, 0, TRUE, FALSE, 0);
288        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
289        gtk_widget_show (box2);
290       
291        /* Args are: homogeneous, spacing, expand, fill, padding */
292        box2 = make_box (TRUE, 0, TRUE, TRUE, 0);
293        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
294        gtk_widget_show (box2);
295       
296        /* Another new separator. */
297        separator = gtk_hseparator_new ();
298        /* The last 3 arguments to gtk_box_pack_start are:
299         * expand, fill, padding. */
300        gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
301        gtk_widget_show (separator);
302       
303        break;
304
305    case 2:
306
307        /* Create a new label, remember box1 is a vbox as created
308         * near the beginning of main() */
309        label = gtk_label_new ("gtk_hbox_new (FALSE, 10);");
310        gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
311        gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
312        gtk_widget_show (label);
313       
314        /* Args are: homogeneous, spacing, expand, fill, padding */
315        box2 = make_box (FALSE, 10, TRUE, FALSE, 0);
316        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
317        gtk_widget_show (box2);
318       
319        /* Args are: homogeneous, spacing, expand, fill, padding */
320        box2 = make_box (FALSE, 10, TRUE, TRUE, 0);
321        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
322        gtk_widget_show (box2);
323       
324        separator = gtk_hseparator_new ();
325        /* The last 3 arguments to gtk_box_pack_start are:
326         * expand, fill, padding. */
327        gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
328        gtk_widget_show (separator);
329       
330        label = gtk_label_new ("gtk_hbox_new (FALSE, 0);");
331        gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
332        gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
333        gtk_widget_show (label);
334       
335        /* Args are: homogeneous, spacing, expand, fill, padding */
336        box2 = make_box (FALSE, 0, TRUE, FALSE, 10);
337        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
338        gtk_widget_show (box2);
339       
340        /* Args are: homogeneous, spacing, expand, fill, padding */
341        box2 = make_box (FALSE, 0, TRUE, TRUE, 10);
342        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
343        gtk_widget_show (box2);
344       
345        separator = gtk_hseparator_new ();
346        /* The last 3 arguments to gtk_box_pack_start are: expand, fill, padding. */
347        gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
348        gtk_widget_show (separator);
349        break;
350   
351    case 3:
352
353        /* This demonstrates the ability to use gtk_box_pack_end() to
354         * right justify widgets. First, we create a new box as before. */
355        box2 = make_box (FALSE, 0, FALSE, FALSE, 0);
356
357        /* Create the label that will be put at the end. */
358        label = gtk_label_new ("end");
359        /* Pack it using gtk_box_pack_end(), so it is put on the right
360         * side of the hbox created in the make_box() call. */
361        gtk_box_pack_end (GTK_BOX (box2), label, FALSE, FALSE, 0);
362        /* Show the label. */
363        gtk_widget_show (label);
364       
365        /* Pack box2 into box1 (the vbox remember ? :) */
366        gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
367        gtk_widget_show (box2);
368       
369        /* A separator for the bottom. */
370        separator = gtk_hseparator_new ();
371        /* This explicitly sets the separator to 400 pixels wide by 5 pixels
372         * high. This is so the hbox we created will also be 400 pixels wide,
373         * and the "end" label will be separated from the other labels in the
374         * hbox. Otherwise, all the widgets in the hbox would be packed as
375         * close together as possible. */
376        gtk_widget_set_usize (separator, 400, 5);
377        /* pack the separator into the vbox (box1) created near the start
378         * of main() */
379        gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
380        gtk_widget_show (separator);   
381    }
382   
383    /* Create another new hbox.. remember we can use as many as we need! */
384    quitbox = gtk_hbox_new (FALSE, 0);
385   
386    /* Our quit button. */
387    button = gtk_button_new_with_label ("Quit");
388   
389    /* Setup the signal to terminate the program when the button is clicked */
390    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
391                               GTK_SIGNAL_FUNC (gtk_main_quit),
392                               GTK_OBJECT (window));
393    /* Pack the button into the quitbox.
394     * The last 3 arguments to gtk_box_pack_start are:
395     * expand, fill, padding. */
396    gtk_box_pack_start (GTK_BOX (quitbox), button, TRUE, FALSE, 0);
397    /* pack the quitbox into the vbox (box1) */
398    gtk_box_pack_start (GTK_BOX (box1), quitbox, FALSE, FALSE, 0);
399   
400    /* Pack the vbox (box1) which now contains all our widgets, into the
401     * main window. */
402    gtk_container_add (GTK_CONTAINER (window), box1);
403   
404    /* And show everything left */
405    gtk_widget_show (button);
406    gtk_widget_show (quitbox);
407   
408    gtk_widget_show (box1);
409    /* Showing the window last so everything pops up at once. */
410    gtk_widget_show (window);
411   
412    /* And of course, our main function. */
413    gtk_main ();
414
415    /* Control returns here when gtk_main_quit() is called, but not when
416     * gtk_exit is used. */
417   
418    return(0);
419}
420/* example-end */
421</PRE>
422</CODE></BLOCKQUOTE>
423<P>
424<H2><A NAME="ss4.4">4.4 Packing Using Tables</A>
425</H2>
426
427<P>Let's take a look at another way of packing - Tables. These can be
428extremely useful in certain situations.
429<P>Using tables, we create a grid that we can place widgets in. The
430widgets may take up as many spaces as we specify.
431<P>The first thing to look at, of course, is the gtk_table_new function:
432<P>
433<BLOCKQUOTE><CODE>
434<PRE>
435GtkWidget *gtk_table_new( gint rows,
436                          gint columns,
437                          gint homogeneous );
438</PRE>
439</CODE></BLOCKQUOTE>
440<P>The first argument is the number of rows to make in the table, while
441the second, obviously, is the number of columns.
442<P>The homogeneous argument has to do with how the table's boxes are
443sized. If homogeneous is TRUE, the table boxes are resized to the size
444of the largest widget in the table. If homogeneous is FALSE, the size
445of a table boxes is dictated by the tallest widget in its same row,
446and the widest widget in its column.
447<P>The rows and columns are laid out from 0 to n, where n was the number
448specified in the call to gtk_table_new. So, if you specify rows = 2
449and columns = 2, the layout would look something like this:
450<P>
451<BLOCKQUOTE><CODE>
452<PRE>
453 0          1          2
4540+----------+----------+
455 |          |          |
4561+----------+----------+
457 |          |          |
4582+----------+----------+
459</PRE>
460</CODE></BLOCKQUOTE>
461<P>Note that the coordinate system starts in the upper left hand corner.
462To place a widget into a box, use the following function:
463<P>
464<BLOCKQUOTE><CODE>
465<PRE>
466void gtk_table_attach( GtkTable  *table,
467                       GtkWidget *child,
468                       gint       left_attach,
469                       gint       right_attach,
470                       gint       top_attach,
471                       gint       bottom_attach,
472                       gint       xoptions,
473                       gint       yoptions,
474                       gint       xpadding,
475                       gint       ypadding );
476</PRE>
477</CODE></BLOCKQUOTE>
478                                       
479<P>The first argument ("table") is the table you've created and the
480second ("child") the widget you wish to place in the table.
481<P>The left and right attach arguments specify where to place the widget,
482and how many boxes to use. If you want a button in the lower right
483table entry of our 2x2 table, and want it to fill that entry ONLY,
484left_attach would be = 1, right_attach = 2, top_attach = 1,
485bottom_attach = 2.
486<P>Now, if you wanted a widget to take up the whole top row of our 2x2
487table, you'd use left_attach = 0, right_attach = 2, top_attach = 0,
488bottom_attach = 1.
489<P>The xoptions and yoptions are used to specify packing options and may
490be bitwise OR'ed together to allow multiple options.
491<P>These options are:
492<UL>
493<LI><CODE>GTK_FILL</CODE> - If the table box is larger than the widget, and
494<CODE>GTK_FILL</CODE> is specified, the widget will expand to use all the room
495available.
496</LI>
497<LI><CODE>GTK_SHRINK</CODE> - If the table widget was allocated less space
498then was requested (usually by the user resizing the window), then the
499widgets would normally just be pushed off the bottom of the window and
500disappear. If <CODE>GTK_SHRINK</CODE> is specified, the widgets will shrink
501with the table.
502</LI>
503<LI><CODE>GTK_EXPAND</CODE> - This will cause the table to expand to use up
504any remaining space in the window.</LI>
505</UL>
506<P>Padding is just like in boxes, creating a clear area around the widget
507specified in pixels.
508<P>gtk_table_attach() has a LOT of options.  So, there's a shortcut:
509<P>
510<BLOCKQUOTE><CODE>
511<PRE>
512void gtk_table_attach_defaults( GtkTable  *table,
513                                GtkWidget *widget,
514                                gint       left_attach,
515                                gint       right_attach,
516                                gint       top_attach,
517                                gint       bottom_attach );
518</PRE>
519</CODE></BLOCKQUOTE>
520<P>The X and Y options default to <CODE>GTK_FILL | GTK_EXPAND</CODE>, and X and Y
521padding are set to 0. The rest of the arguments are identical to the
522previous function.
523<P>We also have gtk_table_set_row_spacing() and
524gtk_table_set_col_spacing(). These places spacing between the rows at
525the specified row or column.
526<P>
527<BLOCKQUOTE><CODE>
528<PRE>
529void gtk_table_set_row_spacing( GtkTable *table,
530                                gint      row,
531                                gint      spacing );
532</PRE>
533</CODE></BLOCKQUOTE>
534<P>and
535<P>
536<BLOCKQUOTE><CODE>
537<PRE>
538void gtk_table_set_col_spacing ( GtkTable *table,
539                                 gint      column,
540                                 gint      spacing );
541</PRE>
542</CODE></BLOCKQUOTE>
543<P>Note that for columns, the space goes to the right of the column, and
544for rows, the space goes below the row.
545<P>You can also set a consistent spacing of all rows and/or columns with:
546<P>
547<BLOCKQUOTE><CODE>
548<PRE>
549void gtk_table_set_row_spacings( GtkTable *table,
550                                 gint      spacing );
551</PRE>
552</CODE></BLOCKQUOTE>
553<P>And,
554<P>
555<BLOCKQUOTE><CODE>
556<PRE>
557void gtk_table_set_col_spacings( GtkTable *table,
558                                 gint      spacing );
559</PRE>
560</CODE></BLOCKQUOTE>
561<P>Note that with these calls, the last row and last column do not get
562any spacing.
563<P>
564<H2><A NAME="ss4.5">4.5 Table Packing Example</A>
565</H2>
566
567<P>Here we make a window with three buttons in a 2x2 table.
568The first two buttons will be placed in the upper row.
569A third, quit button, is placed in the lower row, spanning both columns.
570Which means it should look something like this:
571<P> <CENTER >
572<IMG SRC="gtk_tut_table.gif" VSPACE="15" HSPACE="10"
573ALT="Table Packing Example Image" WIDTH="180" HEIGHT="120"
574> </CENTER
575 >
576<P>Here's the source code:
577<P>
578<BLOCKQUOTE><CODE>
579<PRE>
580/* example-start table table.c */
581
582#include &lt;gtk/gtk.h>
583
584/* Our callback.
585 * The data passed to this function is printed to stdout */
586void callback( GtkWidget *widget,
587               gpointer   data )
588{
589    g_print ("Hello again - %s was pressed\n", (char *) data);
590}
591
592/* This callback quits the program */
593gint delete_event( GtkWidget *widget,
594                   GdkEvent  *event,
595                   gpointer   data )
596{
597    gtk_main_quit ();
598    return(FALSE);
599}
600
601int main( int   argc,
602          char *argv[] )
603{
604    GtkWidget *window;
605    GtkWidget *button;
606    GtkWidget *table;
607
608    gtk_init (&amp;argc, &amp;argv);
609
610    /* Create a new window */
611    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
612
613    /* Set the window title */
614    gtk_window_set_title (GTK_WINDOW (window), "Table");
615
616    /* Set a handler for delete_event that immediately
617     * exits GTK. */
618    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
619                        GTK_SIGNAL_FUNC (delete_event), NULL);
620
621    /* Sets the border width of the window. */
622    gtk_container_set_border_width (GTK_CONTAINER (window), 20);
623
624    /* Create a 2x2 table */
625    table = gtk_table_new (2, 2, TRUE);
626
627    /* Put the table in the main window */
628    gtk_container_add (GTK_CONTAINER (window), table);
629
630    /* Create first button */
631    button = gtk_button_new_with_label ("button 1");
632
633    /* When the button is clicked, we call the "callback" function
634     * with a pointer to "button 1" as its argument */
635    gtk_signal_connect (GTK_OBJECT (button), "clicked",
636              GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
637
638
639    /* Insert button 1 into the upper left quadrant of the table */
640    gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 1, 0, 1);
641
642    gtk_widget_show (button);
643
644    /* Create second button */
645
646    button = gtk_button_new_with_label ("button 2");
647
648    /* When the button is clicked, we call the "callback" function
649     * with a pointer to "button 2" as its argument */
650    gtk_signal_connect (GTK_OBJECT (button), "clicked",
651              GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
652    /* Insert button 2 into the upper right quadrant of the table */
653    gtk_table_attach_defaults (GTK_TABLE(table), button, 1, 2, 0, 1);
654
655    gtk_widget_show (button);
656
657    /* Create "Quit" button */
658    button = gtk_button_new_with_label ("Quit");
659
660    /* When the button is clicked, we call the "delete_event" function
661     * and the program exits */
662    gtk_signal_connect (GTK_OBJECT (button), "clicked",
663                        GTK_SIGNAL_FUNC (delete_event), NULL);
664
665    /* Insert the quit button into the both
666     * lower quadrants of the table */
667    gtk_table_attach_defaults (GTK_TABLE(table), button, 0, 2, 1, 2);
668
669    gtk_widget_show (button);
670
671    gtk_widget_show (table);
672    gtk_widget_show (window);
673
674    gtk_main ();
675
676    return 0;
677}
678/* example-end */
679</PRE>
680</CODE></BLOCKQUOTE>
681<P>
682<HR NOSHADE>
683<A HREF="gtk_tut-5.html">Next</A>
684<A HREF="gtk_tut-3.html">Previous</A>
685<A HREF="gtk_tut.html#toc4">Contents</A>
686</BODY>
687</HTML>
Note: See TracBrowser for help on using the repository browser.