📄 gtkfaq.txt
字号:
You should notice the backquote character which is used in this command line. A common mistake when you start a GTK+ based development is to use quote instead of backquotes. If you do so, the compiler will complain about an unknown file called 'gtk-config --cflags --libs'. The text in backquotes is an instruction to your shell to substitute the output of executing this text into the command line. The command line above ensure that: +o the correct C compiler flags will be used to compile the program (including the complete C header directory list) +o your program will be linked with the needed libraries. 44..33.. WWhhaatt aabboouutt uussiinngg tthhee mmaakkee uuttiilliittyy?? This is a sample makefile which compile a GTK+ based program: # basic GTK+ app makefile SOURCES = myprg.c foo.c bar.c OBJS = ${SOURCES:.c=.o} CFLAGS = `gtk-config --cflags` LDADD = `gtk-config --libs` CC = gcc PACKAGE = myprg all : ${OBJS} ${CC} -o ${PACKAGE} ${OBJS} ${LDADD} .c.o: ${CC} ${CFLAGS} -c $< # end of file For more information about the make utility, you should read either the related man page or the relevant info file. 44..44.. II uussee tthhee bbaacckkqquuoottee ssttuuffff iinn mmyy mmaakkeeffiilleess,, bbuutt mmyy mmaakkee pprroocceessss ffaaiilleedd.. The backquote construction seems to not be accepted by some old make utilities. If you use one of these, the make process will probably fail. In order to have the backquote syntax working again, you should use the GNU make utility (get it on the GNU ftp server at ftp://ftp.gnu.org/). 44..55.. II wwaanntt ttoo aadddd ssoommee ccoonnffiigguurree ssttuuffff,, hhooww ccoouulldd II ddoo tthhiiss?? To use autoconf/automake, you must first install the relevant packages. These are: +o the m4 preprocessor v1.4 or better +o autoconf v2.13 or better +o automake v1.4 or better You'll find these packages on the GNU main ftp server (ftp://ftp.gnu.org/) or on any GNU mirror. In order to use the powerfull autoconf/automake scheme, you must create a configure.in which may look like: dnl Process this file with autoconf to produce a configure script. dnl configure.in for a GTK+ based program AC_INIT(myprg.c)dnl AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl AM_CONFIG_HEADER(config.h)dnl dnl Checks for programs. AC_PROG_CC dnl check for the c compiler dnl you should add CFLAGS="" here, 'cos it is set to -g by PROG_CC dnl Checks for libraries. AM_PATH_GTK(1.2.0,,AC_MSG_ERROR(mypkgname 0.1 needs GTK))dnl AC_OUTPUT( Makefile )dnl You must add a Makefile.am file: bin_PROGRAMS = myprg myprg_SOURCES = myprg.c foo.c bar.c INCLUDES = @GTK_CFLAGS@ LDADD = @GTK_LIBS@ CLEANFILES = *~ DISTCLEANFILES = .deps/*.P then, to use these, simply type the following commands: aclocal autoheader autoconf automake --add-missing --include-deps --foreign For further informations, you should look at the autoconf and the automake documentation (the shipped info files are really easy to understand, and there are plenty of web resources that deal with autoconf and/or automake). 44..66.. II ttrryy ttoo ddeebbuugg mmyy GGTTKK++ aapppplliiccaattiioonn wwiitthh ggddbb,, bbuutt iitt hhaannggss mmyy XX sseerrvveerr wwhheenn II hhiitt ssoommee bbrreeaakkppooiinntt.. AAnnyy IIddeeaa ?? From Federico Mena Quintero: X is not locked up. It is likely that you are hitting a breakpoint inside a callback that is called from a place in Gtk that has a mouse grab. Run your program with the "--sync" option; it will make it easier to debug. Also, you may want to use the console for running the debugger, and just let the program run in another console with the X server. Eric Mouw had another solution: An old terminal connected to an otherwise unused serial port is also great for debugging X programs. Old vt100/vt220 ter- minals are dirt cheap but a bit hard to get (here in The Netherlands, YMMV). 55.. DDeevveellooppmmeenntt wwiitthh GGTTKK++:: ggeenneerraall qquueessttiioonnss 55..11.. WWhhaatt wwiiddggeettss aarree iinn GGTTKK?? The GTK+ Tutorial lists the following widgets: 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 55..22.. IIss GGTTKK++ tthhrreeaadd ssaaffee?? HHooww ddoo II wwrriittee mmuullttii--tthhrreeaaddeedd GGTTKK++ aapppplliiccaa-- ttiioonnss?? The GLib library can be used in a thread-safe mode by calling g_thread_init() before making any other GLib calls. In this mode GLib automatically locks all internal data structures as needed. This does not mean that two threads can simultaneously access, for example, a single hash table, but they can access two different hash tables simultaneously. If two different threads need to access the same hash table, the application is responsible for locking itself. When GLib is intialized to be thread-safe, GTK+ is _t_h_r_e_a_d _a_w_a_r_e. There is a single global lock that you must acquire with gdk_threads_enter() before making any GDK calls, and release with gdk_threads_leave() afterwards. A minimal main program for a threaded GTK+ application looks like: int main (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); } Callbacks require a bit of attention. Callbacks from GTK+ (signals) are made within the GTK+ lock. However callbacks from GLib (timeouts, IO callbacks, and idle functions) are made outside of the GTK+ lock. So, within a signal handler you do not need to call gdk_threads_enter(), but within the other types of callbacks, you do. 55..33.. WWhhyy ddoo tthhiiss ssttrraannggee ''xx iioo eerrrroorr'' ooccccuurr wwhheenn II ffoorrkk(()) iinn mmyy GGTTKK++ aapppp?? This is not really a GTK+ problem, and the problem is not related to fork() too. If the 'x io error' occurs then you probably use the exit() function in order to exit from the child process. When GDK opens an X display, it creates a socket file descriptor. When you use the 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 _exit(). Erik Mouw gave the following piece of code about the fork()/exit() problem (slightly modified) 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -