📄 gtk_tut-2.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><HTML><HEAD> <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9"> <TITLE>GTK v1.2 Tutorial: Getting Started</TITLE> <LINK HREF="gtk_tut-3.html" REL=next> <LINK HREF="gtk_tut-1.html" REL=previous> <LINK HREF="gtk_tut.html#toc2" REL=contents></HEAD><BODY BGCOLOR="#FFFFFF"><A HREF="gtk_tut-3.html">Next</A><A HREF="gtk_tut-1.html">Previous</A><A HREF="gtk_tut.html#toc2">Contents</A><HR NOSHADE><H2><A NAME="s2">2. Getting Started</A></H2><P>The first thing to do of course, is download the GTK source andinstall it. You can always get the latest version from ftp.gtk.org in/pub/gtk. You can also view other sources of GTK information onhttp://www.gtk.org/ <A HREF="http://www.gtk.org/">http://www.gtk.org/</A>. GTK uses GNU autoconf for configuration.Once untar'd, type ./configure --help to see a list of options.<P>Th GTK source distribution also contains the complete source to all ofthe examples used in this tutorial, along with Makefiles to aidcompilation.<P>To begin our introduction to GTK, we'll start with the simplestprogram possible. This program will create a 200x200 pixel window andhas no way of exiting except to be killed using the shell.<P><BLOCKQUOTE><CODE><PRE>/* example-start base base.c */#include <gtk/gtk.h>int main( int argc, char *argv[] ){ GtkWidget *window; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_show (window); gtk_main (); return(0);}/* example-end */</PRE></CODE></BLOCKQUOTE><P>You can compile the above program with gcc using:<BLOCKQUOTE><CODE><PRE>gcc base.c -o base `gtk-config --cflags --libs`</PRE></CODE></BLOCKQUOTE><P>The meaning of the unusual compilation options is explained below.<P>All programs will of course include gtk/gtk.h which declares thevariables, functions, structures etc. that will be used in your GTKapplication.<P>The next line:<P><BLOCKQUOTE><CODE><PRE>gtk_init (&argc, &argv);</PRE></CODE></BLOCKQUOTE><P>calls the function gtk_init(gint *argc, gchar ***argv) which will becalled in all GTK applications. This sets up a few things for us suchas the default visual and color map and then proceeds to callgdk_init(gint *argc, gchar ***argv). This function initializes thelibrary for use, sets up default signal handlers, and checks thearguments passed to your application on the command line, looking forone of the following:<P><UL><LI> <CODE>--gtk-module</CODE></LI><LI> <CODE>--g-fatal-warnings</CODE></LI><LI> <CODE>--gtk-debug</CODE></LI><LI> <CODE>--gtk-no-debug</CODE></LI><LI> <CODE>--gdk-debug</CODE></LI><LI> <CODE>--gdk-no-debug</CODE></LI><LI> <CODE>--display</CODE></LI><LI> <CODE>--sync</CODE></LI><LI> <CODE>--no-xshm</CODE></LI><LI> <CODE>--name</CODE></LI><LI> <CODE>--class</CODE></LI></UL><P>It removes these from the argument list, leaving anything it does notrecognize for your application to parse or ignore. This creates a setof standard arguments accepted by all GTK applications.<P>The next two lines of code create and display a window.<P><BLOCKQUOTE><CODE><PRE> window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_show (window);</PRE></CODE></BLOCKQUOTE><P>The GTK_WINDOW_TOPLEVEL argument specifies that we want the window toundergo window manager decoration and placement. Rather than create awindow of 0x0 size, a window without children is set to 200x200 bydefault so you can still manipulate it.<P>The gtk_widget_show() function lets GTK know that we are done settingthe attributes of this widget, and that it can display it.<P>The last line enters the GTK main processing loop.<P><BLOCKQUOTE><CODE><PRE> gtk_main ();</PRE></CODE></BLOCKQUOTE><P>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 tooccur. In our simple example however, events are ignored.<P><H2><A NAME="ss2.1">2.1 Hello World in GTK</A></H2><P>Now for a program with a widget (a button). It's the classichello world a la GTK.<P><BLOCKQUOTE><CODE><PRE>/* example-start helloworld helloworld.c */#include <gtk/gtk.h>/* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */void hello( GtkWidget *widget, gpointer data ){ g_print ("Hello World\n");}gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ){ /* 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. */ g_print ("delete event occurred\n"); /* Change TRUE to FALSE and the main window will be destroyed with * a "delete_event". */ return(TRUE);}/* Another callback */void destroy( GtkWidget *widget, gpointer data ){ gtk_main_quit();}int main( int argc, char *argv[] ){ /* GtkWidget is the storage type for widgets */ GtkWidget *window; GtkWidget *button; /* This is called in all GTK applications. Arguments are parsed * from the command line and are returned to the application. */ gtk_init(&argc, &argv); /* create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* 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. */ 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. */ 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". */ button = gtk_button_new_with_label ("Hello World"); /* When the button receives the "clicked" signal, it will call the * function hello() passing it NULL as its argument. The hello() * function is defined above. */ 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 * 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). */ gtk_container_add (GTK_CONTAINER (window), button); /* The final step is to display this newly created widget. */ gtk_widget_show (button); /* and the window */ gtk_widget_show (window); /* 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). */ gtk_main (); return(0);}/* example-end */</PRE></CODE></BLOCKQUOTE><P><H2><A NAME="ss2.2">2.2 Compiling Hello World</A></H2><P>To compile use:<P><BLOCKQUOTE><CODE><PRE>gcc -Wall -g helloworld.c -o helloworld `gtk-config --cflags` \ `gtk-config --libs`</PRE></CODE></BLOCKQUOTE><P>This uses the program <CODE>gtk-config</CODE>, which comes with gtk. Thisprogram 'knows' what compiler switches are needed to compile programsthat use gtk. <CODE>gtk-config --cflags</CODE> will output a list of includedirectories for the compiler to look in, and <CODE>gtk-config --libs</CODE>will output the list of libraries for the compiler to link with andthe directories to find them in. In the aboce example they could havebeen combined into a single instance, such as`gtk-config --cflags --libs`.<P>Note that the type of single quote used in the compile command aboveis significant.<P>The libraries that are usually linked in are:<UL><LI>The GTK library (-lgtk), the widget library, based on top of GDK.</LI><LI>The GDK library (-lgdk), the Xlib wrapper.</LI><LI>The gmodule library (-lgmodule), which is used to load run timeextensions.</LI><LI>The glib library (-lglib), containing miscellaneous functions, onlyg_print() is used in this particular example. GTK is built on topof glib so you will always require this library. See the section on <A HREF="gtk_tut-20.html#sec_glib">glib</A> for details.</LI><LI>The Xlib library (-lX11) which is used by GDK.</LI><LI>The Xext library (-lXext). This contains code for shared memorypixmaps and other X extensions.</LI><LI>The math library (-lm). This is used by GTK for various purposes.</LI></UL><P><H2><A NAME="ss2.3">2.3 Theory of Signals and Callbacks</A></H2><P>Before we look in detail at <EM>helloworld</EM>, we'll discuss signalsand callbacks. GTK is an event driven toolkit, which means it willsleep in gtk_main until an event occurs and control is passed to theappropriate function.<P>This passing of control is done using the idea of "signals". When anevent occurs, such as the press of a mouse button, the appropriatesignal will be "emitted" by the widget that was pressed. This is howGTK does most of its useful work. There are a set of signals that allwidgets inherit, such as "destroy", and there are signals that arewidget specific, such as "toggled" on a toggle button.<P>To make a button perform an action, we set up a signal handler tocatch these signals and call the appropriate function. This is done byusing a function such as:<P><BLOCKQUOTE><CODE><PRE>gint gtk_signal_connect( GtkObject *object, gchar *name, GtkSignalFunc func, gpointer func_data );</PRE></CODE></BLOCKQUOTE><P>Where the first argument is the widget which will be emitting thesignal, and the second, the name of the signal you wish to catch. Thethird is the function you wish to be called when it is caught, and thefourth, the data you wish to have passed to this function.<P>The function specified in the third argument is called a "callbackfunction", and should generally be of the form:<P><BLOCKQUOTE><CODE><PRE>void callback_func( GtkWidget *widget, gpointer callback_data );</PRE></CODE></BLOCKQUOTE><P>Where the first argument will be a pointer to the widget that emittedthe signal, and the second, a pointer to the data given as the lastargument to the gtk_signal_connect() function as shown above.<P>Note that the above form for a signal callback function declaration isonly a general guide, as some widget specific signals generatedifferent calling parameters. For example, the GtkCList "select_row"signal provides both row and column parameters.<P>Another call used in the <EM>helloworld</EM> example, is:<P><BLOCKQUOTE><CODE><PRE>gint gtk_signal_connect_object( GtkObject *object, gchar *name, GtkSignalFunc func, GtkObject *slot_object );</PRE></CODE></BLOCKQUOTE><P>gtk_signal_connect_object() is the same as gtk_signal_connect() exceptthat the callback function only uses one argument, a pointer to a GTKobject. So when using this function to connect signals, the callbackshould be of the form:<P><BLOCKQUOTE><CODE><PRE>void callback_func( GtkObject *object );</PRE></CODE></BLOCKQUOTE><P>Where the object is usually a widget. We usually don't setup callbacksfor gtk_signal_connect_object however. They are usually used to call aGTK function that accepts a single widget or object as an argument, asis the case in our <EM>helloworld</EM> example.<P>The purpose of having two functions to connect signals is simply toallow the callbacks to have a different number of arguments. Manyfunctions in the GTK library accept only a single GtkWidget pointer asan argument, so you want to use the gtk_signal_connect_object() forthese, whereas for your functions, you may need to have additionaldata supplied to the callbacks.<P><H2><A NAME="ss2.4">2.4 Events</A></H2><P>In addition to the signal mechanism described above, there are a setof <EM>events</EM> that reflect the X event mechanism. Callbacks mayalso be attached to these events. These events are:<P><UL><LI> event</LI>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -