📄 gtkfaq.sgml
字号:
<item>autoconf v2.13 or better <item>automake v1.4 or better</itemize>You'll find these packages on the GNU main ftp server (<htmlurl url="ftp://ftp.gnu.org/" name="ftp://ftp.gnu.org/">) or on any GNU mirror.In order to use the powerfull autoconf/automake scheme, you must createa configure.in which may look like:<tscreen><verb>dnl Process this file with autoconf to produce a configure script.dnl configure.in for a GTK+ based programAC_INIT(myprg.c)dnlAM_INIT_AUTOMAKE(mypkbname,0.0.1)dnlAM_CONFIG_HEADER(config.h)dnldnl Checks for programs.AC_PROG_CC dnl check for the c compilerdnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CCdnl Checks for libraries.AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnlAC_OUTPUT( Makefile)dnl</verb></tscreen>You must add a Makefile.am file:<tscreen><verb>bin_PROGRAMS = myprgmyprg_SOURCES = myprg.c foo.c bar.cINCLUDES = @GTK_CFLAGS@LDADD = @GTK_LIBS@CLEANFILES = *~DISTCLEANFILES = .deps/*.P</verb></tscreen>then, to use these, simply type the following commands:<verb>aclocalautoheaderautoconfautomake --add-missing --include-deps --foreign </verb>For further informations, you should look at the autoconf and the automakedocumentation (the shipped info files are really easy to understand, and thereare plenty of web resources that deal with autoconf and/or automake).<!-- ----------------------------------------------------------------- --><sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?<p>From Federico Mena Quintero:<quote>X is not locked up. It is likely that you are hitting a breakpointinside a callback that is called from a place in Gtk that has a mousegrab.<P>Run your program with the "--sync" option; it will make it easier todebug. Also, you may want to use the console for running thedebugger, and just let the program run in another console with the Xserver.</quote>Eric Mouw had another solution:<quote>An old terminal connected to an otherwise unused serial port is also greatfor debugging X programs. Old vt100/vt220 terminals are dirt cheap but abit hard to get (here in The Netherlands, YMMV).</quote><!-- ***************************************************************** --><sect>Development with GTK+: general questions<!-- ***************************************************************** --><!-- ----------------------------------------------------------------- --><sect1>What widgets are in GTK?<p>The GTK+ Tutorial lists the following widgets:<verb> GtkObject +GtkData | +GtkAdjustment | `GtkTooltips `GtkWidget +GtkContainer | +GtkBin | | +GtkAlignment | | +GtkEventBox | | +GtkFrame | | | `GtkAspectFrame | | +GtkHandleBox | | +GtkItem | | | +GtkListItem | | | +GtkMenuItem | | | | `GtkCheckMenuItem | | | | `GtkRadioMenuItem | | | `GtkTreeItem | | +GtkViewport | | `GtkWindow | | +GtkColorSelectionDialog | | +GtkDialog | | | `GtkInputDialog | | `GtkFileSelection | +GtkBox | | +GtkButtonBox | | | +GtkHButtonBox | | | `GtkVButtonBox | | +GtkHBox | | | +GtkCombo | | | `GtkStatusbar | | `GtkVBox | | +GtkColorSelection | | `GtkGammaCurve | +GtkButton | | +GtkOptionMenu | | `GtkToggleButton | | `GtkCheckButton | | `GtkRadioButton | +GtkCList | `GtkCTree | +GtkFixed | +GtkList | +GtkMenuShell | | +GtkMenuBar | | `GtkMenu | +GtkNotebook | +GtkPaned | | +GtkHPaned | | `GtkVPaned | +GtkScrolledWindow | +GtkTable | +GtkToolbar | `GtkTree +GtkDrawingArea | `GtkCurve +GtkEditable | +GtkEntry | | `GtkSpinButton | `GtkText +GtkMisc | +GtkArrow | +GtkImage | +GtkLabel | | `GtkTipsQuery | `GtkPixmap +GtkPreview +GtkProgressBar +GtkRange | +GtkScale | | +GtkHScale | | `GtkVScale | `GtkScrollbar | +GtkHScrollbar | `GtkVScrollbar +GtkRuler | +GtkHRuler | `GtkVRuler `GtkSeparator +GtkHSeparator `GtkVSeparator</verb><!-- ----------------------------------------------------------------- --><sect1>Is GTK+ thread safe? How do I write multi-threaded GTK+ applications?<p>The GLib library can be used in a thread-safe mode by callingg_thread_init() before making any other GLib calls. In this mode GLibautomatically locks all internal data structures as needed. Thisdoes not mean that two threads can simultaneously access, forexample, a single hash table, but they can access two different hashtables simultaneously. If two different threads need to access thesame hash table, the application is responsible for lockingitself.When GLib is intialized to be thread-safe, GTK+ is<em>thread aware</em>. There is a single global lockthat you must acquire with gdk_threads_enter() beforemaking any GDK calls, and release with gdk_threads_leave()afterwards.A minimal main program for a threaded GTK+ applicationlooks like:<verb>intmain (int argc, char *argv[]){ GtkWidget *window; g_thread_init(NULL); gtk_init(&argc, &argv); window = create_window(); gtk_widget_show(window); gdk_threads_enter(); gtk_main(); gdk_threads_leave(); return(0);}</verb>Callbacks require a bit of attention. Callbacks from GTK+(signals) are made within the GTK+ lock. However callbacksfrom GLib (timeouts, IO callbacks, and idle functions)are made outside of the GTK+ lock. So, within a signalhandler you do not need to call gdk_threads_enter(), butwithin the other types of callbacks, you do.<!-- This is the old answer - TRGAlthough GTK+, like many X toolkits, isn't thread safe, this doesnot prohibit the development of multi-threaded applications withGTK+. Rob Browning (rlb@cs.utexas.edu) describes threading techniques foruse with GTK+ (slightly edited): There are basically two main approaches, the first is simple, and thesecond complicated. In the first, you just make sure that all GTK+ (orX) interactions are handled by one, andonly one, thread. Any other thread that wants to draw something hasto somehow notify the "GTK+" thread, and let it handle theactual work. The second approach allows you to call GTK+ (or X) functions from anythread, but it requires some careful synchronization. Thebasic idea is that you create an X protection mutex, and no one maymake any X calls without first acquiring this mutex. Note that this is a little effort, but it allows you to bepotentially more efficient than a completely thread safe GTK+. Youget to decide the granularity of the thread locking. You also have tomake sure that the thread that calls <tt/gtk_main()/ is holding the lock whenit calls <tt/gtk_main()/.The next thing to worry about is that since you were holding theglobal mutex when you entered <tt/gtk_main()/, all callbacks will also beholding it. This means that the callback must release it if it'sgoing to call any other code that might reacquire it. Otherwiseyou'll get deadlock. Also, you must be holding the mutex when youfinally return from the callback. In order to allow threads other than the one calling <tt/gtk_main/ toget access to the mutex, we also need to register a work functionwith GTK that allows us to release the mutex periodically.Why can't GTK+ be thread safe by default? Complexity, overhead, and manpower. The proportion of threadedprograms is still reasonably small, and getting thread safety right isboth quite difficult and takes valuable time away from the main workof getting a good graphics library finished. It would be nice to haveGTK+ thread safe "out of the box", but that's not practical right now,and it also might make GTK+ substantially less efficient if not handledcarefully.Regardless, it's especially not a priority since relatively goodworkarounds exist. --><!-- ----------------------------------------------------------------- --><sect1>Why do this strange 'x io error' occur when I <tt/fork()/ in my GTK+ app?<p>This is not really a GTK+ problem, and the problem is not related to <tt/fork()/too. If the 'x io error' occurs then you probably use the <tt/exit()/ functionin order to exit from the child process.When GDK opens an X display, it creates a socket file descriptor. When you usethe <tt/exit()/ function, you implicitly close all the open file descriptors,and the underlying X library really doesn't like this.The right function to use here is <tt/_exit()/. Erik Mouw gave the following piece of code about the fork()/exit() problem(slightly modified)<tscreen><verb> int pid = fork(); if(pid==-1) { perror("fork"); exit(-1); } else if(pid==0) /* child */ { retval=system("a command"); /* can use exec* functions here */ _exit(retval); /* notice _exit() instead of exit() */ } else /* parent */ { for(;;) { if(waitpid(pid, &status, WNOHANG) == pid) { waitpid(pid, &status, WUNTRACED); /* anti zombie code */ break; } } return(WEXITSTATUS(status)); }</verb></tscreen><!-- ----------------------------------------------------------------- --><sect1>Why don't the contents of a button move when the button is pressed? Here's a patch to make it work that way...<p>From: Peter Mattis<quote>The reason buttons don't move their child down and to the right whenthey are depressed is because I don't think that's what is happeningvisually. My view of buttons is that you are looking at them straighton. That is, the user interface lies in a plane and you're above itlooking straight at it. When a button gets pressed it moves directlyaway from you. To be absolutely correct I guess the child shouldactually shrink a tiny amount. But I don't see why the child shouldshift down and to the left. Remember, the child is supposed to beattached to the buttons surface. Its not good for it to appear likethe child is slipping on the surface of the button.<P>On a more practical note, I did implement this at one point anddetermined it didn't look good and removed it.</quote> <!-- ----------------------------------------------------------------- --><sect1>How to I identifiy a widgets top level window or other ancestor?<p>There are a couple of ways to find the top level parent of awidget. The easier way is to call the <tt/gtk_widget_top_level()/function that returns a pointer to a GtkWidget that is the top levelwindow.A more complicated way to do this (but less limited, as it allowsthe user to get the closest ancestor of a known type) is to use<tt/gtk_widget_get_ancestor()/ as in:<tscreen><verb> GtkWidget *widget; widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);</verb></tscreen>Since virtually all the GTK_TYPEs can be used as the second parameter ofthis function, you can get any parent widget of a particularwidget. Suppose you have an hbox which contains a vbox, which in turn containssome other atomic widget (entry, label, etc. To find the master hboxusing the <tt/entry/ widget simply use:<tscreen><verb> GtkWidget *hbox; hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);</verb></tscreen><!-- ----------------------------------------------------------------- -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -