+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
+Thu Mar 9 22:10:56 GMT 2000 Tony Gale <gale@gtk.org>
+
+ * docs/gtkfaq.sgml: FAQ Update:
+ - Minor cleanups (Emmanuel, me)
+ - New questions:
+ I need to add a new signal to a GTK+ widget. Any idea? (timj)
+ How can I retrieve the text from a GtkMenuItem? (timj)
+ How do I validate/limit/filter the input to a GtkEntry? (me)
+ Memory does not seem to be released when I free the list
+ nodes I've allocated (timj)
+
2000-03-07 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkmain-win32.c: Internal GDK error reporting changes:
<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
-<date>February 22nd 2000
+<date>March 9th 2000
<abstract> This document is intended to answer questions that are likely to be
frequently asked by programmers using GTK+ or people who are just looking at
<p>
GTK+ == Gimp Toolkit
-GDK == Gtk+ Drawing Kit
+GDK == GTK+ Drawing Kit
GLib == G Libray
<!-- ***************************************************************** -->
<sect>How to find, configure, install, and troubleshoot GTK+
-
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
</itemize>
+<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure/compile GTK+?
<p>
Generally, all you will need to do is issue the commands:
<sect1>When compiling GTK+ I get an error like:
<tt/make: file `Makefile' line 456: Syntax error/
<p>
-Make sure that you are using GNU make (use <tt/make -v/ to check). There are
-many weird and wonderful versions of make out there, and not all of them
-handle the automatically generated Makefiles.
+Make sure that you are using GNU make (use <tt/make -v/ to
+check). There are many weird and wonderful versions of make out there,
+and not all of them handle the automatically generated Makefiles.
<!-- ----------------------------------------------------------------- -->
<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
<p>
-This problem is most often encountered when the GTK+ libraries can't be
-found or are the wrong version. Generally, the compiler will complain about an
-'unresolved symbol'. There are two things you need to check:
+This problem is most often encountered when the GTK+ libraries can't
+be found or are the wrong version. Generally, the compiler will
+complain about an 'unresolved symbol'. There are two things you need
+to check:
<itemize>
-<item>Make sure that the libraries can be found. You want to edit
-/etc/ld.so.conf to include the directories which contain the GTK libraries,
- so it looks something like:
+<item>Make sure that the libraries can be found. You want to edit
+/etc/ld.so.conf to include the directories which contain the GTK
+libraries, so it looks something like:
<verb>
/usr/X11R6/lib
/usr/local/lib
<verb>
rpm -e gtk gtk-devel
</verb>
-You may also want to remove the packages that depend on gtk (rpm will tell you
-which ones they are). If you don't have a RedHat Linux system, check to make sure
-that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
-the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
-(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk)
-and reinstall gtk+.
-</itemize>
+You may also want to remove the packages that depend on gtk (rpm will
+tell you which ones they are). If you don't have a RedHat Linux
+system, check to make sure that neither <verb>/usr/lib</verb> or
+<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
+libgdk, libglib, or libgck. If they do exist, remove them (and any
+gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
+reinstall gtk+. </itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
The CVS toolset is available as RPM packages from the usual RedHat sites.
The latest version is available at
<htmlurl url="http://download.cyclic.com/pub/"
-name="<http://download.cyclic.com/pub/>">
+name="http://download.cyclic.com/pub/">
Anyone can download the latest CVS version of GTK+ by using anonymous access
using the following steps:
<verb>
cvs -z3 get glib
</verb>
-
</itemize>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How can I contribute to GTK+?
<p>
<!-- ----------------------------------------------------------------- -->
<sect1>Is anyone working on bindings for languages other than C?
<p>
-The GTK+ home page (<htmlurl url="http://www.gtk.org/"
+The GTK+ home page (<htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">) presents a list of GTK+ bindings.
<itemize>
<!-- ***************************************************************** -->
<sect>Development with GTK+: the begining
<!-- ***************************************************************** -->
+
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I get started?
<p>
So, after you have installed GTK+ there are a couple of things that can
ease you into developing applications with it. There is the
GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
-name="<http://www.gtk.org/tutorial/>">, which is undergoing
+name="http://www.gtk.org/tutorial/">, which is undergoing
development. This will introduce you to writing applications using C.
The Tutorial doesn't (yet) contain information on all of the widgets
</itemize>
+<!-- ----------------------------------------------------------------- -->
<sect1>What about using the <tt/make/ utility?
<p>
This is a sample makefile which compile a GTK+ based program:
dnl configure.in for a GTK+ based program
AC_INIT(myprg.c)dnl
-AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
+AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
AM_CONFIG_HEADER(config.h)dnl
dnl Checks for programs.
DISTCLEANFILES = .deps/*.P
</verb></tscreen>
+If your project contains more than one subdirectory, you'll have to
+create one Makefile.am in each directory plus a master Makefile.am
+which will look like:
+
+<tscreen><verb>
+SUBDIRS = mydir1 mydir2 mydir3
+</verb></tscreen>
+
then, to use these, simply type the following commands:
<verb>
automake --add-missing --include-deps --foreign
</verb>
-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).
+For further information, 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 automake).
<!-- ----------------------------------------------------------------- -->
<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
<!-- ***************************************************************** -->
<sect>Development with GTK+: general questions
<!-- ***************************************************************** -->
+
<!-- ----------------------------------------------------------------- -->
<sect1>What widgets are in GTK?
<p>
<!-- This is the old answer - TRG
-
Although GTK+, like many X toolkits, isn't thread safe, this does
not prohibit the development of multi-threaded applications with
GTK+.
carefully.
Regardless, it's especially not a priority since relatively good
-workarounds exist. -->
+workarounds exist.
+-->
+
<!-- ----------------------------------------------------------------- -->
<sect1>Why does 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()/
-either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
-in order to exit from the child process.
+This is not really a GTK+ problem, and the problem is not related to
+<tt/fork()/ either. If the 'x io error' occurs then you probably use
+the <tt/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 <tt/exit()/ function, you implicitly close all the open file descriptors,
-and the underlying X library really doesn't like this.
+When GDK opens an X display, it creates a socket file descriptor. When
+you use the <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 contributed the following code example to illustrate handling
-fork() and exit().
+Erik Mouw contributed the following code example to illustrate
+handling fork() and exit().
<tscreen><verb>
/*-------------------------------------------------------------------------
widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
</verb></tscreen>
-Since virtually all the GTK_TYPEs can be used as the second parameter of
-this function, you can get any parent widget of a particular
-widget. Suppose you have an hbox which contains a vbox, which in turn contains
-some other atomic widget (entry, label, etc. To find the master hbox
-using the <tt/entry/ widget simply use:
+Since virtually all the GTK_TYPEs can be used as the second parameter
+of this function, you can get any parent widget of a particular
+widget. Suppose you have an hbox which contains a vbox, which in turn
+contains some other atomic widget (entry, label, etc. To find the
+master hbox using the <tt/entry/ widget simply use:
<tscreen><verb>
GtkWidget *hbox;
<!-- ----------------------------------------------------------------- -->
<sect1>By the way, what are the differences between signals and events?
<p>
-First of all, Havoc Pennington gives a rather complete description of the
-differences between events and signals in his free book (two chapters can
-be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
+First of all, Havoc Pennington gives a rather complete description of
+the differences between events and signals in his free book (two
+chapters can be found at <htmlurl
+url="http://www106.pair.com/rhp/sample_chapters.html"
name="http://www106.pair.com/rhp/sample_chapters.html">).
Moreover, Havoc posted this to the <tt/gtk-list/
<quote>
- Events are a stream of messages received from the X server. They drive the
- Gtk main loop; which more or less amounts to "wait for events, process
- them" (not exactly, it is really more general than that and can wait on
- many different input streams at once). Events are a Gdk/Xlib concept.
+ Events are a stream of messages received from the X server. They
+ drive the Gtk main loop; which more or less amounts to "wait for
+ events, process them" (not exactly, it is really more general than
+ that and can wait on many different input streams at once). Events
+ are a Gdk/Xlib concept.
<P>
- Signals are a feature of GtkObject and its subclasses. They have nothing
- to do with any input stream; really a signal is just a way to keep a list
- of callbacks around and invoke them ("emit" the signal). There are lots of
- details and extra features of course. Signals are emitted by object
- instances, and are entirely unrelated to the Gtk main loop.
- Conventionally, signals are emitted "when something changes" about the
- object emitting the signal.
+ Signals are a feature of GtkObject and its subclasses. They have
+ nothing to do with any input stream; really a signal is just a way
+ to keep a list of callbacks around and invoke them ("emit" the
+ signal). There are lots of details and extra features of
+ course. Signals are emitted by object instances, and are entirely
+ unrelated to the Gtk main loop. Conventionally, signals are emitted
+ "when something changes" about the object emitting the signal.
<P>
- Signals and events only come together because GtkWidget happens to emit
- signals when it gets events. This is purely a convenience, so you can
- connect callbacks to be invoked when a particular widget receives a
- particular event. There is nothing about this that makes signals and
- events inherently related concepts, any more than emitting a signal when
- you click a button makes button clicking and signals related concepts.
+ Signals and events only come together because GtkWidget happens to
+ emit signals when it gets events. This is purely a convenience, so
+ you can connect callbacks to be invoked when a particular widget
+ receives a particular event. There is nothing about this that makes
+ signals and events inherently related concepts, any more than
+ emitting a signal when you click a button makes button clicking and
+ signals related concepts.
</quote>
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
<p>
-There is some special initialisation to do in order to catch some
-particular events. In fact, you must set the correct event mask bit of your
-widget before getting some particular events.
+There is some special initialisation to do in order to catch some
+particular events. In fact, you must set the correct event mask bit of
+your widget before getting some particular events.
For example,
All the event masks are defined in the <tt/gdktypes.h/ file.
+<!-- ----------------------------------------------------------------- -->
+<sect1>I need to add a new signal to a GTK+ widget. Any idea?
+<p>
+If the signal you want to add may be beneficial for other GTK+ users,
+you may want to submit a patch that presents your changes. Check the
+tutorial for more information about adding signals to a widget class.
+
+If you don't think it is the case or if your patch is not applied
+you'll have to use the <tt/gtk_object_class_user_signal_new/
+function. <tt/gtk_object_class_user_signal_new/ allows you to add a
+new signal to a predefined GTK+ widget without any modification of the
+GTK+ source code. The new signal can be emited with
+<tt/gtk_signal_emit/ and can be handled in the same way as other
+signals.
+
+Tim Janik posted this code snippet:
+
+<tscreen><verb>
+static guint signal_user_action = 0;
+
+signal_user_action =
+ gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
+ "user_action",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_POINTER);
+
+void
+gtk_widget_user_action (GtkWidget *widget,
+ gpointer act_data)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
+}
+</verb></tscreen>
+
+If you want your new signal to have more than the classical gpointer
+parameter, you'll have to play with GTK+ marshallers.
+
<!-- ----------------------------------------------------------------- -->
<sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
<p>
<sect1>Why doesn't my widget (e.g. progressbar) update?
<p>
-You are probably doing all the changes within a function
-without returning control to <tt/gtk_main()/. This may be the case if you do some
-lengthy calculation in your code. Most drawing updates are only
+You are probably doing all the changes within a function without
+returning control to <tt/gtk_main()/. This may be the case if you do
+some lengthy calculation in your code. Most drawing updates are only
placed on a queue, which is processed within <tt/gtk_main()/. You can
force the drawing queue to be processed using something like:
<!-- ----------------------------------------------------------------- -->
<sect1>How do I attach data to some GTK+ object/widget?
<p>
-First of all, the attached data is stored in the object_data field of a
-GtkObject. The type of this field is GData, which is defined in glib.h.
-So you should read the gdataset.c file in your glib source directory very
-carefully.
+First of all, the attached data is stored in the object_data field of
+a GtkObject. The type of this field is GData, which is defined in
+glib.h. So you should read the gdataset.c file in your glib source
+directory very carefully.
-There are two (easy) ways to attach some data to a gtk object.
-Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the
-most common way to do this, as it provides a powerful interface
-to connect objects and data.
+There are two (easy) ways to attach some data to a gtk object. Using
+<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
+the most common way to do this, as it provides a powerful interface to
+connect objects and data.
<tscreen><verb>
void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
+
gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I remove the data I have attached to an object?
<p>
-When attaching the data to the object, you can use the
-<tt/gtk_object_set_data_full()/
-function. The three first arguments of the function are the same as in
-<tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
-which is called when the data is destroyed. The data is destroyed when
-you:
+When attaching the data to the object, you can use the
+<tt/gtk_object_set_data_full()/ function. The three first arguments of
+the function are the same as in <tt/gtk_object_set_data()/. The fourth
+one is a pointer to a callback function which is called when the data
+is destroyed. The data is destroyed when you:
<itemize>
<item> destroy the object
<!-- ----------------------------------------------------------------- -->
<sect1>How could I get any widgets position?
<p>
-As Tim Janik pointed out, there are different cases, and each case requires
-a different solution.
+As Tim Janik pointed out, there are different cases, and each case
+requires a different solution.
<itemize>
<item> If you want the position of a widget relative to its parent,
The <tt/gtk_widget_set_uposition()/ function is used to set the
position of any widget.
-The <tt/gtk_widget_set_usize()/ function is used to set the
-size of a widget. In order to use all the features that are provided by
-this function when it acts on a window, you may want to use the
+The <tt/gtk_widget_set_usize()/ function is used to set the size of a
+widget. In order to use all the features that are provided by this
+function when it acts on a window, you may want to use the
<tt/gtk_window_set_policy/ function. The definition of these functions
are:
<tt/Auto_shrink/ will automatically shrink the window when the
requested size of the child widgets goes below the current size of the
-window. <tt/Allow_shrink/ will give the user the authorisation to
-make the window smaller that it should normally be. <tt/Allow_grow/
-will give the user will have the ability to make the window
-bigger. The default values for these parameters are:
+window. <tt/Allow_shrink/ will give the user the authorisation to make
+the window smaller that it should normally be. <tt/Allow_grow/ will
+give the user will have the ability to make the window bigger. The
+default values for these parameters are:
<tscreen><verb>
allow_shrink = FALSE
set a window size since you cannot decrease this window size with
another call to this function unless you call it twice, as in:
+<tscreen><verb>
gtk_widget_set_usize(your_widget, -1, -1);
gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
+</verb></tscreen>
Another way to set the size of and/or move a window is to use the
<tt/gdk_window_move_resize()/ function which uses to work fine both to
grow or to shrink the window:
+<tscreen><verb>
gdk_window_move_resize(window->window,
x_pos, y_pos,
x_size, y_size);
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add a popup menu to my GTK+ application?
<p>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I disable or enable a widget, such as a button?
<p>
-To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
-function. The first parameter is you widget pointer. The second parameter
-is a boolean value: when this value is TRUE, the widget is enabled.
+To disable (or to enable) a widget, use the
+<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
+widget pointer. The second parameter is a boolean value: when this
+value is TRUE, the widget is enabled.
<!-- ----------------------------------------------------------------- -->
<sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
char) into "const gchar *[]" (array of an unspecified number of
pointers to const char).
-The type qualifier "const" may be subject to automatic casting, but
-in the array case, it is not the array itself that needs the (const)
+The type qualifier "const" may be subject to automatic casting, but in
+the array case, it is not the array itself that needs the (const)
qualified cast, but its members, thus changing the whole type.
<!-- ----------------------------------------------------------------- -->
selection_mode GTK_LIST()->selection contents
------------------------------------------------------
-GTK_SELECTION_SINGLE) selection is either NULL
+GTK_SELECTION_SINGLE selection is either NULL
or contains a GList* pointer
for a single selected item.
-GTK_SELECTION_BROWSE) selection is NULL if the list
+GTK_SELECTION_BROWSE selection is NULL if the list
contains no widgets, otherwise
it contains a GList* pointer
for one GList structure.
-GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
+
+GTK_SELECTION_MULTIPLE selection is NULL if no listitems
are selected or a a GList* pointer
for the first selected item. that
in turn points to a GList structure
for the second selected item and so
- on
+ on.
-GTK_SELECTION_EXTENDED) selection is NULL.
+GTK_SELECTION_EXTENDED selection is NULL.
</verb>
The data field of the GList structure GTK_LIST(MyGtkList)->selection points
<!-- ----------------------------------------------------------------- -->
<sect1>How do I catch a combo box change?
<p>
-The entry which is associated to your GtkCombo send a "changed" signal when:
+The entry which is associated to your GtkCombo send a "changed" signal
+when:
<itemize>
<item>some text is typed in
<item>the selection of the combo box is changed
<!-- ----------------------------------------------------------------- -->
<sect1>How can I right justify a menu, such as Help?
<p>
-Depending on if you use the MenuFactory or not, there are two ways to proceed.
-With the MenuFactory, use something like the following:
+Depending on if you use the MenuFactory or not, there are two ways to
+proceed. With the MenuFactory, use something like the following:
<tscreen><verb>
menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add some underlined accelerators to menu items?
<p>
-Damon Chaplin, the technical force behind the Glade project, provided the
-following code sample (this code is an output from Glade). It creates a
-small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/
-and the N in <tt/New/ are underlined, and the relevant accelerators are
-created.
+Damon Chaplin, the technical force behind the Glade project, provided
+the following code sample (this code is an output from Glade). It
+creates a small <tt/File/ menu item with only one child
+(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
+and the relevant accelerators are created.
<tscreen><verb>
menubar1 = gtk_menu_bar_new ();
gtk_container_add (GTK_CONTAINER (file1_menu), new1);
</verb></tscreen>
+<!-- ----------------------------------------------------------------- -->
+<sect1>How can I retrieve the text from a GtkMenuItem?
+<p>
+You can usually retrieve the label of a specific GtkMenuItem with:
+
+<tscreen><verb>
+ if (GTK_BIN (menu_item)->child)
+ {
+ GtkWidget *child = GTK_BIN (menu_item)->child;
+
+ /* do stuff with child */
+ if (GTK_IS_LABEL (child))
+ {
+ gchar *text;
+
+ gtk_label_get (GTK_LABEL (child), &text);
+ g_print ("menu item text: %s\n", text);
+ }
+ }
+</verb></tscreen>
+
+To get the active menu item from a GtkOptionMenu you can do:
+<tscreen><verb>
+if (GTK_OPTION_MENU (option_menu)->menu_item)
+{
+ GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
+}
+</verb></tscreen>
+
+But, there's a catch. For this specific case, you can <bf>not</bf> get
+the label widget from <tt/menu_item/ with the above code, because the
+option menu reparents the menu_item's child temporarily to display the
+currently active contents. So to retrive the child of the currently
+active menu_item of an option menu, you'll have to do:
+
+<tscreen><verb>
+ if (GTK_BIN (option_menu)->child)
+ {
+ GtkWidget *child = GTK_BIN (option_menu)->child;
+
+ /* do stuff with child */
+ }
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I right (or otherwise) justify a GtkLabel?
<p>
-Are you sure you want to <em>justify</em> the labels? The label class contains
-the <tt/gtk_label_set_justify()/ function that is used to control the
-justification of a multi-line label.
+Are you sure you want to <em>justify</em> the labels? The label class
+contains the <tt/gtk_label_set_justify()/ function that is used to
+control the justification of a multi-line label.
-What you probably want is to set the <em>alignment</em> of the label, ie right
-align it, center it or left align it. If you want to do this, you
-should use:
+What you probably want is to set the <em>alignment</em> of the label,
+ie right align it, center it or left align it. If you want to do this,
+you should use:
<tscreen><verb>
void gtk_misc_set_alignment (GtkMisc *misc,
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure Tooltips in a Resource File?
<p>
-The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
-a GtkWidget (though a GtkObject) and as such is not attempted to match any
-widget styles.
+The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
+not a GtkWidget (though a GtkObject) and as such is not attempted to
+match any widget styles.
So, you resource file should look something like:
<verb>
NULL);
</verb></tscreen>
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I validate/limit/filter the input to a GtkEntry?
+<p>
+If you want to validate the text that a user enters into a GtkEntry
+widget you can attach to the "insert_text" signal of the entry, and
+modify the text within the callback function. The example below forces
+all characters to uppercase, and limits the range of characters to
+A-Z. Note that the entry is cast to an object of type GtkEditable,
+from which GtkEntry is derived.
+
+<tscreen><verb>
+#include <ctype.h>
+#include <gtk/gtk.h>
+
+void insert_text_handler (GtkEntry *entry,
+ const gchar *text,
+ gint length,
+ gint *position,
+ gpointer data)
+{
+ GtkEditable *editable = GTK_EDITABLE(entry);
+ int i, count=0;
+ gchar *result = g_new (gchar, length);
+
+ for (i=0; i < length; i++) {
+ if (!isalpha(text[i]))
+ continue;
+ result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
+ }
+
+ if (count > 0) {
+ gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (insert_text_handler),
+ data);
+ gtk_editable_insert_text (editable, result, count, position);
+ gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (insert_text_handler),
+ data);
+ }
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
+
+ g_free (result);
+}
+
+int main (int argc,
+ char *argv[])
+{
+ GtkWidget *window;
+ GtkWidget *entry;
+
+ gtk_init (&argc, &argv);
+
+ /* create a new window */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
+ gtk_signal_connect(GTK_OBJECT (window), "delete_event",
+ (GtkSignalFunc) gtk_exit, NULL);
+
+ entry = gtk_entry_new();
+ gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
+ GTK_SIGNAL_FUNC(insert_text_handler),
+ NULL);
+ gtk_container_add(GTK_CONTAINER (window), entry);
+ gtk_widget_show(entry);
+
+ gtk_widget_show(window);
+
+ gtk_main();
+ return(0);
+}
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I use horizontal scrollbars with a GtkText widget?
<p>
Notice that the response is valid for any object that inherits from the
GtkEditable class.
-Are you sure that you want to move the cursor position? Most of the time,
-while the cursor position is good, the insertion point does not match the
-cursor position. If this apply to what you really want, then you should use
-the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
-at the current cursor position, use the following:
+Are you sure that you want to move the cursor position? Most of the
+time, while the cursor position is good, the insertion point does not
+match the cursor position. If this apply to what you really want, then
+you should use the <tt/gtk_text_set_point()/ function. If you want to
+set the insertion point at the current cursor position, use the
+following:
<tscreen><verb>
gtk_text_set_point(GTK_TEXT(text),
- gtk_editable_get_position(GTK_EDITABLE(text)));
+ gtk_editable_get_position(GTK_EDITABLE(text)));
</verb></tscreen>
If you want the insertion point to follow the cursor at all time, you
should probably catch the button press event, and then move the
-insertion point. Be careful : you'll have to catch it after the widget
-has changed the cursor position though. Thomas Mailund Jensen proposed the
-following code:
+insertion point. Be careful : you'll have to catch it after the widget
+has changed the cursor position though. Thomas Mailund Jensen proposed
+the following code:
<tscreen><verb>
static void
{
/* jump to cursor mark */
gtk_text_set_point (GTK_TEXT (text),
- gtk_editable_get_position (GTK_EDITABLE (text)));
+ gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
"bar", strlen ("bar"));
<!-- ----------------------------------------------------------------- -->
<sect1>What is GDK?
<p>
-GDK is basically a wrapper around the standard Xlib function calls. If you are
-at all familiar with Xlib, a lot of the functions in GDK will require little
-or no getting used to. All functions are written to provide an way
-to access Xlib functions in an easier and slightly more intuitive manner.
-In addition, since GDK uses GLib (see below), it will be more portable
-and safer to use on multiple platforms.
+GDK is basically a wrapper around the standard Xlib function calls. If
+you are at all familiar with Xlib, a lot of the functions in GDK will
+require little or no getting used to. All functions are written to
+provide an way to access Xlib functions in an easier and slightly more
+intuitive manner. In addition, since GDK uses GLib (see below), it
+will be more portable and safer to use on multiple platforms.
<!-- Examples, anybody? I've been mulling some over. NF -->
<!-- I believe it should be better :) ED -->
<!-- Linked lists are pretty standard data structures - don't want to
over do it - TRG -->
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Memory does not seem to be released when I free the list nodes I've allocated
+<p>
+GLib tries to be "intelligent" on this special issue: it assumes that
+you are likely to reuse the objects, so caches the allocated memory.
+If you do not want to use this behavior, you'll probably want to set
+up a special allocator.
+
+To quote Tim Janik:
+<quote>
+If you have a certain portion of code that uses *lots* of GLists or
+GNodes, and you know you'd better want to release all of them after a
+short while, you'd want to use a GAllocator. Pushing an allocator into
+g_list will make all subsequent glist operations private to that
+allocator's memory pool (and thus you have to take care to pop the
+allocator again, before making any external calls):
+</quote>
+
+<tscreen><verb>
+GAllocator *allocator;
+GList *list = NULL;
+guint i;
+
+/* set a new allocation pool for GList nodes */
+allocator = g_allocator_new ("list heap", 1024);
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+for (i = 0; i < 4096; i++)
+ list = g_list_prepend (list, NULL);
+list = g_list_reverse (list);
+
+/* beware to pop allocator befor calling external functions */
+g_list_pop_allocator ();
+gtk_label_set_text (GTK_LABEL (some_label), "some text");
+
+/* and set our private glist pool again */
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+g_list_free (list);
+list = NULL;
+for (i = 0; i < 4096; i++)
+ list = g_list_prepend (list, NULL);
+
+/* and back out (while freeing all of the list nodes in our pool) */
+g_list_pop_allocator ();
+g_allocator_free (allocator);
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
<p>
Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
<quote>
-Regarding g_malloc(), g_free() and siblings, these functions are much safer
-than their libc equivalents. For example, g_free() just returns if called
-with NULL. Also, if USE_DMALLOC is defined, the definition for these
-functions changes (in glib.h) to use MALLOC(), FREE() etc... If MEM_PROFILE
-or MEM_CHECK are defined, there are even small statistics made counting
-the used block sizes (shown by g_mem_profile() / g_mem_check()).
-<P>
+Regarding g_malloc(), g_free() and siblings, these functions are much
+safer than their libc equivalents. For example, g_free() just returns
+if called with NULL. Also, if USE_DMALLOC is defined, the definition
+for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
+If MEM_PROFILE or MEM_CHECK are defined, there are even small
+statistics made counting the used block sizes (shown by
+g_mem_profile() / g_mem_check()).
+<p>
Considering the fact that glib provides an interface for memory chunks
to save space if you have lots of blocks that are always the same size
and to mark them ALLOC_ONLY if needed, it is just straight forward to
create a small saver (debug able) wrapper around the normal malloc/free
stuff as well - just like gdk covers Xlib. ;)
-<P>
+<p>
Using g_error() and g_warning() inside of applications like the GIMP
that fully rely on gtk even gives the opportunity to pop up a window
showing the messages inside of a gtk window with your own handler
You need to understand that the scanner will parse its input and
tokenize it, it is up to you to interpret these tokens, not define
-their types before they get parsed, e.g. watch gscanner parse a string:
+their types before they get parsed, e.g. watch gscanner parse a
+string:
<verb>
"hi i am 17"
<htmlurl url="mailto:amundson@gimp.org"
name="<amundson@gimp.org>"> who continues to provide support.
-Contributions should be sent to Tony Gale <htmlurl url="mailto:gale@gtk.org"
-name="<gale@gtk.org>">
+Contributions should be sent to Tony Gale <htmlurl
+url="mailto:gale@gtk.org" name="<gale@gtk.org>">
The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson,
Tony Gale, Emmanuel Deloget and Nathan Froyd.
<!-- NOTE: Use only one author tag, otherwise sgml2txt barfs - TRG -->
<author>Tony Gale, Shawn T. Amundson, Emmanuel Deloget, Nathan Froyd
-<date>February 22nd 2000
+<date>March 9th 2000
<abstract> This document is intended to answer questions that are likely to be
frequently asked by programmers using GTK+ or people who are just looking at
<p>
GTK+ == Gimp Toolkit
-GDK == Gtk+ Drawing Kit
+GDK == GTK+ Drawing Kit
GLib == G Libray
<!-- ***************************************************************** -->
<sect>How to find, configure, install, and troubleshoot GTK+
-
<!-- ***************************************************************** -->
<!-- ----------------------------------------------------------------- -->
<item>US - ftp://ftp.insync.net/pub/mirrors/ftp.gimp.org/
</itemize>
+<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure/compile GTK+?
<p>
Generally, all you will need to do is issue the commands:
<sect1>When compiling GTK+ I get an error like:
<tt/make: file `Makefile' line 456: Syntax error/
<p>
-Make sure that you are using GNU make (use <tt/make -v/ to check). There are
-many weird and wonderful versions of make out there, and not all of them
-handle the automatically generated Makefiles.
+Make sure that you are using GNU make (use <tt/make -v/ to
+check). There are many weird and wonderful versions of make out there,
+and not all of them handle the automatically generated Makefiles.
<!-- ----------------------------------------------------------------- -->
<sect1>I've compiled and installed GTK+, but I can't get any programs to link with it!
<p>
-This problem is most often encountered when the GTK+ libraries can't be
-found or are the wrong version. Generally, the compiler will complain about an
-'unresolved symbol'. There are two things you need to check:
+This problem is most often encountered when the GTK+ libraries can't
+be found or are the wrong version. Generally, the compiler will
+complain about an 'unresolved symbol'. There are two things you need
+to check:
<itemize>
-<item>Make sure that the libraries can be found. You want to edit
-/etc/ld.so.conf to include the directories which contain the GTK libraries,
- so it looks something like:
+<item>Make sure that the libraries can be found. You want to edit
+/etc/ld.so.conf to include the directories which contain the GTK
+libraries, so it looks something like:
<verb>
/usr/X11R6/lib
/usr/local/lib
<verb>
rpm -e gtk gtk-devel
</verb>
-You may also want to remove the packages that depend on gtk (rpm will tell you
-which ones they are). If you don't have a RedHat Linux system, check to make sure
-that neither <verb>/usr/lib</verb> or <verb>/usr/local/lib</verb> contain any of
-the libraries libgtk, libgdk, libglib, or libgck. If they do exist, remove them
-(and any gtk include files, such as /usr/include/gtk and /usr/include/gdk)
-and reinstall gtk+.
-</itemize>
+You may also want to remove the packages that depend on gtk (rpm will
+tell you which ones they are). If you don't have a RedHat Linux
+system, check to make sure that neither <verb>/usr/lib</verb> or
+<verb>/usr/local/lib</verb> contain any of the libraries libgtk,
+libgdk, libglib, or libgck. If they do exist, remove them (and any
+gtk include files, such as /usr/include/gtk and /usr/include/gdk) and
+reinstall gtk+. </itemize>
<!-- ----------------------------------------------------------------- -->
<sect1>When compiling programs with GTK+, I get compiler error messages about not being able to find <tt/"glibconfig.h"/.
The CVS toolset is available as RPM packages from the usual RedHat sites.
The latest version is available at
<htmlurl url="http://download.cyclic.com/pub/"
-name="<http://download.cyclic.com/pub/>">
+name="http://download.cyclic.com/pub/">
Anyone can download the latest CVS version of GTK+ by using anonymous access
using the following steps:
<verb>
cvs -z3 get glib
</verb>
-
</itemize>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How can I contribute to GTK+?
<p>
<!-- ----------------------------------------------------------------- -->
<sect1>Is anyone working on bindings for languages other than C?
<p>
-The GTK+ home page (<htmlurl url="http://www.gtk.org/"
+The GTK+ home page (<htmlurl url="http://www.gtk.org/"
name="http://www.gtk.org/">) presents a list of GTK+ bindings.
<itemize>
<!-- ***************************************************************** -->
<sect>Development with GTK+: the begining
<!-- ***************************************************************** -->
+
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I get started?
<p>
So, after you have installed GTK+ there are a couple of things that can
ease you into developing applications with it. There is the
GTK+ Tutorial <htmlurl url="http://www.gtk.org/tutorial/"
-name="<http://www.gtk.org/tutorial/>">, which is undergoing
+name="http://www.gtk.org/tutorial/">, which is undergoing
development. This will introduce you to writing applications using C.
The Tutorial doesn't (yet) contain information on all of the widgets
</itemize>
+<!-- ----------------------------------------------------------------- -->
<sect1>What about using the <tt/make/ utility?
<p>
This is a sample makefile which compile a GTK+ based program:
dnl configure.in for a GTK+ based program
AC_INIT(myprg.c)dnl
-AM_INIT_AUTOMAKE(mypkbname,0.0.1)dnl
+AM_INIT_AUTOMAKE(mypkgname,0.0.1)dnl
AM_CONFIG_HEADER(config.h)dnl
dnl Checks for programs.
DISTCLEANFILES = .deps/*.P
</verb></tscreen>
+If your project contains more than one subdirectory, you'll have to
+create one Makefile.am in each directory plus a master Makefile.am
+which will look like:
+
+<tscreen><verb>
+SUBDIRS = mydir1 mydir2 mydir3
+</verb></tscreen>
+
then, to use these, simply type the following commands:
<verb>
automake --add-missing --include-deps --foreign
</verb>
-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).
+For further information, 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 automake).
<!-- ----------------------------------------------------------------- -->
<sect1>I try to debug my GTK+ application with gdb, but it hangs my X server when I hit some breakpoint. Any Idea ?
<!-- ***************************************************************** -->
<sect>Development with GTK+: general questions
<!-- ***************************************************************** -->
+
<!-- ----------------------------------------------------------------- -->
<sect1>What widgets are in GTK?
<p>
<!-- This is the old answer - TRG
-
Although GTK+, like many X toolkits, isn't thread safe, this does
not prohibit the development of multi-threaded applications with
GTK+.
carefully.
Regardless, it's especially not a priority since relatively good
-workarounds exist. -->
+workarounds exist.
+-->
+
<!-- ----------------------------------------------------------------- -->
<sect1>Why does 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()/
-either. If the 'x io error' occurs then you probably use the <tt/exit()/ function
-in order to exit from the child process.
+This is not really a GTK+ problem, and the problem is not related to
+<tt/fork()/ either. If the 'x io error' occurs then you probably use
+the <tt/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 <tt/exit()/ function, you implicitly close all the open file descriptors,
-and the underlying X library really doesn't like this.
+When GDK opens an X display, it creates a socket file descriptor. When
+you use the <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 contributed the following code example to illustrate handling
-fork() and exit().
+Erik Mouw contributed the following code example to illustrate
+handling fork() and exit().
<tscreen><verb>
/*-------------------------------------------------------------------------
widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);
</verb></tscreen>
-Since virtually all the GTK_TYPEs can be used as the second parameter of
-this function, you can get any parent widget of a particular
-widget. Suppose you have an hbox which contains a vbox, which in turn contains
-some other atomic widget (entry, label, etc. To find the master hbox
-using the <tt/entry/ widget simply use:
+Since virtually all the GTK_TYPEs can be used as the second parameter
+of this function, you can get any parent widget of a particular
+widget. Suppose you have an hbox which contains a vbox, which in turn
+contains some other atomic widget (entry, label, etc. To find the
+master hbox using the <tt/entry/ widget simply use:
<tscreen><verb>
GtkWidget *hbox;
<!-- ----------------------------------------------------------------- -->
<sect1>By the way, what are the differences between signals and events?
<p>
-First of all, Havoc Pennington gives a rather complete description of the
-differences between events and signals in his free book (two chapters can
-be found at <htmlurl url="http://www106.pair.com/rhp/sample_chapters.html"
+First of all, Havoc Pennington gives a rather complete description of
+the differences between events and signals in his free book (two
+chapters can be found at <htmlurl
+url="http://www106.pair.com/rhp/sample_chapters.html"
name="http://www106.pair.com/rhp/sample_chapters.html">).
Moreover, Havoc posted this to the <tt/gtk-list/
<quote>
- Events are a stream of messages received from the X server. They drive the
- Gtk main loop; which more or less amounts to "wait for events, process
- them" (not exactly, it is really more general than that and can wait on
- many different input streams at once). Events are a Gdk/Xlib concept.
+ Events are a stream of messages received from the X server. They
+ drive the Gtk main loop; which more or less amounts to "wait for
+ events, process them" (not exactly, it is really more general than
+ that and can wait on many different input streams at once). Events
+ are a Gdk/Xlib concept.
<P>
- Signals are a feature of GtkObject and its subclasses. They have nothing
- to do with any input stream; really a signal is just a way to keep a list
- of callbacks around and invoke them ("emit" the signal). There are lots of
- details and extra features of course. Signals are emitted by object
- instances, and are entirely unrelated to the Gtk main loop.
- Conventionally, signals are emitted "when something changes" about the
- object emitting the signal.
+ Signals are a feature of GtkObject and its subclasses. They have
+ nothing to do with any input stream; really a signal is just a way
+ to keep a list of callbacks around and invoke them ("emit" the
+ signal). There are lots of details and extra features of
+ course. Signals are emitted by object instances, and are entirely
+ unrelated to the Gtk main loop. Conventionally, signals are emitted
+ "when something changes" about the object emitting the signal.
<P>
- Signals and events only come together because GtkWidget happens to emit
- signals when it gets events. This is purely a convenience, so you can
- connect callbacks to be invoked when a particular widget receives a
- particular event. There is nothing about this that makes signals and
- events inherently related concepts, any more than emitting a signal when
- you click a button makes button clicking and signals related concepts.
+ Signals and events only come together because GtkWidget happens to
+ emit signals when it gets events. This is purely a convenience, so
+ you can connect callbacks to be invoked when a particular widget
+ receives a particular event. There is nothing about this that makes
+ signals and events inherently related concepts, any more than
+ emitting a signal when you click a button makes button clicking and
+ signals related concepts.
</quote>
<!-- ----------------------------------------------------------------- -->
<!-- ----------------------------------------------------------------- -->
<sect1>I have my signal connected to the the (whatever) event, but it seems I don't catch it. What's wrong?
<p>
-There is some special initialisation to do in order to catch some
-particular events. In fact, you must set the correct event mask bit of your
-widget before getting some particular events.
+There is some special initialisation to do in order to catch some
+particular events. In fact, you must set the correct event mask bit of
+your widget before getting some particular events.
For example,
All the event masks are defined in the <tt/gdktypes.h/ file.
+<!-- ----------------------------------------------------------------- -->
+<sect1>I need to add a new signal to a GTK+ widget. Any idea?
+<p>
+If the signal you want to add may be beneficial for other GTK+ users,
+you may want to submit a patch that presents your changes. Check the
+tutorial for more information about adding signals to a widget class.
+
+If you don't think it is the case or if your patch is not applied
+you'll have to use the <tt/gtk_object_class_user_signal_new/
+function. <tt/gtk_object_class_user_signal_new/ allows you to add a
+new signal to a predefined GTK+ widget without any modification of the
+GTK+ source code. The new signal can be emited with
+<tt/gtk_signal_emit/ and can be handled in the same way as other
+signals.
+
+Tim Janik posted this code snippet:
+
+<tscreen><verb>
+static guint signal_user_action = 0;
+
+signal_user_action =
+ gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),
+ "user_action",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_POINTER);
+
+void
+gtk_widget_user_action (GtkWidget *widget,
+ gpointer act_data)
+{
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);
+}
+</verb></tscreen>
+
+If you want your new signal to have more than the classical gpointer
+parameter, you'll have to play with GTK+ marshallers.
+
<!-- ----------------------------------------------------------------- -->
<sect1>Is it possible to get some text displayed which is truncated to fit inside its allocation?
<p>
<sect1>Why doesn't my widget (e.g. progressbar) update?
<p>
-You are probably doing all the changes within a function
-without returning control to <tt/gtk_main()/. This may be the case if you do some
-lengthy calculation in your code. Most drawing updates are only
+You are probably doing all the changes within a function without
+returning control to <tt/gtk_main()/. This may be the case if you do
+some lengthy calculation in your code. Most drawing updates are only
placed on a queue, which is processed within <tt/gtk_main()/. You can
force the drawing queue to be processed using something like:
<!-- ----------------------------------------------------------------- -->
<sect1>How do I attach data to some GTK+ object/widget?
<p>
-First of all, the attached data is stored in the object_data field of a
-GtkObject. The type of this field is GData, which is defined in glib.h.
-So you should read the gdataset.c file in your glib source directory very
-carefully.
+First of all, the attached data is stored in the object_data field of
+a GtkObject. The type of this field is GData, which is defined in
+glib.h. So you should read the gdataset.c file in your glib source
+directory very carefully.
-There are two (easy) ways to attach some data to a gtk object.
-Using <tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be the
-most common way to do this, as it provides a powerful interface
-to connect objects and data.
+There are two (easy) ways to attach some data to a gtk object. Using
+<tt/gtk_object_set_data()/ and <tt/gtk_object_get_data()/ seems to be
+the most common way to do this, as it provides a powerful interface to
+connect objects and data.
<tscreen><verb>
void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);
+
gpointer gtk_object_get_data(GtkObject *object, const gchar *key);
</verb></tscreen>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I remove the data I have attached to an object?
<p>
-When attaching the data to the object, you can use the
-<tt/gtk_object_set_data_full()/
-function. The three first arguments of the function are the same as in
-<tt/gtk_object_set_data()/. The fourth one is a pointer to a callback function
-which is called when the data is destroyed. The data is destroyed when
-you:
+When attaching the data to the object, you can use the
+<tt/gtk_object_set_data_full()/ function. The three first arguments of
+the function are the same as in <tt/gtk_object_set_data()/. The fourth
+one is a pointer to a callback function which is called when the data
+is destroyed. The data is destroyed when you:
<itemize>
<item> destroy the object
<!-- ----------------------------------------------------------------- -->
<sect1>How could I get any widgets position?
<p>
-As Tim Janik pointed out, there are different cases, and each case requires
-a different solution.
+As Tim Janik pointed out, there are different cases, and each case
+requires a different solution.
<itemize>
<item> If you want the position of a widget relative to its parent,
The <tt/gtk_widget_set_uposition()/ function is used to set the
position of any widget.
-The <tt/gtk_widget_set_usize()/ function is used to set the
-size of a widget. In order to use all the features that are provided by
-this function when it acts on a window, you may want to use the
+The <tt/gtk_widget_set_usize()/ function is used to set the size of a
+widget. In order to use all the features that are provided by this
+function when it acts on a window, you may want to use the
<tt/gtk_window_set_policy/ function. The definition of these functions
are:
<tt/Auto_shrink/ will automatically shrink the window when the
requested size of the child widgets goes below the current size of the
-window. <tt/Allow_shrink/ will give the user the authorisation to
-make the window smaller that it should normally be. <tt/Allow_grow/
-will give the user will have the ability to make the window
-bigger. The default values for these parameters are:
+window. <tt/Allow_shrink/ will give the user the authorisation to make
+the window smaller that it should normally be. <tt/Allow_grow/ will
+give the user will have the ability to make the window bigger. The
+default values for these parameters are:
<tscreen><verb>
allow_shrink = FALSE
set a window size since you cannot decrease this window size with
another call to this function unless you call it twice, as in:
+<tscreen><verb>
gtk_widget_set_usize(your_widget, -1, -1);
gtk_widget_set_usize(your_widget, new_x_size, new_y_size);
+</verb></tscreen>
Another way to set the size of and/or move a window is to use the
<tt/gdk_window_move_resize()/ function which uses to work fine both to
grow or to shrink the window:
+<tscreen><verb>
gdk_window_move_resize(window->window,
x_pos, y_pos,
x_size, y_size);
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add a popup menu to my GTK+ application?
<p>
<!-- ----------------------------------------------------------------- -->
<sect1>How do I disable or enable a widget, such as a button?
<p>
-To disable (or to enable) a widget, use the <tt/gtk_widget_set_sensitive()/
-function. The first parameter is you widget pointer. The second parameter
-is a boolean value: when this value is TRUE, the widget is enabled.
+To disable (or to enable) a widget, use the
+<tt/gtk_widget_set_sensitive()/ function. The first parameter is you
+widget pointer. The second parameter is a boolean value: when this
+value is TRUE, the widget is enabled.
<!-- ----------------------------------------------------------------- -->
<sect1>Shouldn't the text argument in the gtk_clist_* functions be declared const?
char) into "const gchar *[]" (array of an unspecified number of
pointers to const char).
-The type qualifier "const" may be subject to automatic casting, but
-in the array case, it is not the array itself that needs the (const)
+The type qualifier "const" may be subject to automatic casting, but in
+the array case, it is not the array itself that needs the (const)
qualified cast, but its members, thus changing the whole type.
<!-- ----------------------------------------------------------------- -->
selection_mode GTK_LIST()->selection contents
------------------------------------------------------
-GTK_SELECTION_SINGLE) selection is either NULL
+GTK_SELECTION_SINGLE selection is either NULL
or contains a GList* pointer
for a single selected item.
-GTK_SELECTION_BROWSE) selection is NULL if the list
+GTK_SELECTION_BROWSE selection is NULL if the list
contains no widgets, otherwise
it contains a GList* pointer
for one GList structure.
-GTK_SELECTION_MULTIPLE) selection is NULL if no listitems
+
+GTK_SELECTION_MULTIPLE selection is NULL if no listitems
are selected or a a GList* pointer
for the first selected item. that
in turn points to a GList structure
for the second selected item and so
- on
+ on.
-GTK_SELECTION_EXTENDED) selection is NULL.
+GTK_SELECTION_EXTENDED selection is NULL.
</verb>
The data field of the GList structure GTK_LIST(MyGtkList)->selection points
<!-- ----------------------------------------------------------------- -->
<sect1>How do I catch a combo box change?
<p>
-The entry which is associated to your GtkCombo send a "changed" signal when:
+The entry which is associated to your GtkCombo send a "changed" signal
+when:
<itemize>
<item>some text is typed in
<item>the selection of the combo box is changed
<!-- ----------------------------------------------------------------- -->
<sect1>How can I right justify a menu, such as Help?
<p>
-Depending on if you use the MenuFactory or not, there are two ways to proceed.
-With the MenuFactory, use something like the following:
+Depending on if you use the MenuFactory or not, there are two ways to
+proceed. With the MenuFactory, use something like the following:
<tscreen><verb>
menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
<!-- ----------------------------------------------------------------- -->
<sect1>How do I add some underlined accelerators to menu items?
<p>
-Damon Chaplin, the technical force behind the Glade project, provided the
-following code sample (this code is an output from Glade). It creates a
-small <tt/File/ menu item with only one child (<tt/New/). The F in <tt/File/
-and the N in <tt/New/ are underlined, and the relevant accelerators are
-created.
+Damon Chaplin, the technical force behind the Glade project, provided
+the following code sample (this code is an output from Glade). It
+creates a small <tt/File/ menu item with only one child
+(<tt/New/). The F in <tt/File/ and the N in <tt/New/ are underlined,
+and the relevant accelerators are created.
<tscreen><verb>
menubar1 = gtk_menu_bar_new ();
gtk_container_add (GTK_CONTAINER (file1_menu), new1);
</verb></tscreen>
+<!-- ----------------------------------------------------------------- -->
+<sect1>How can I retrieve the text from a GtkMenuItem?
+<p>
+You can usually retrieve the label of a specific GtkMenuItem with:
+
+<tscreen><verb>
+ if (GTK_BIN (menu_item)->child)
+ {
+ GtkWidget *child = GTK_BIN (menu_item)->child;
+
+ /* do stuff with child */
+ if (GTK_IS_LABEL (child))
+ {
+ gchar *text;
+
+ gtk_label_get (GTK_LABEL (child), &text);
+ g_print ("menu item text: %s\n", text);
+ }
+ }
+</verb></tscreen>
+
+To get the active menu item from a GtkOptionMenu you can do:
+<tscreen><verb>
+if (GTK_OPTION_MENU (option_menu)->menu_item)
+{
+ GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item;
+}
+</verb></tscreen>
+
+But, there's a catch. For this specific case, you can <bf>not</bf> get
+the label widget from <tt/menu_item/ with the above code, because the
+option menu reparents the menu_item's child temporarily to display the
+currently active contents. So to retrive the child of the currently
+active menu_item of an option menu, you'll have to do:
+
+<tscreen><verb>
+ if (GTK_BIN (option_menu)->child)
+ {
+ GtkWidget *child = GTK_BIN (option_menu)->child;
+
+ /* do stuff with child */
+ }
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I right (or otherwise) justify a GtkLabel?
<p>
-Are you sure you want to <em>justify</em> the labels? The label class contains
-the <tt/gtk_label_set_justify()/ function that is used to control the
-justification of a multi-line label.
+Are you sure you want to <em>justify</em> the labels? The label class
+contains the <tt/gtk_label_set_justify()/ function that is used to
+control the justification of a multi-line label.
-What you probably want is to set the <em>alignment</em> of the label, ie right
-align it, center it or left align it. If you want to do this, you
-should use:
+What you probably want is to set the <em>alignment</em> of the label,
+ie right align it, center it or left align it. If you want to do this,
+you should use:
<tscreen><verb>
void gtk_misc_set_alignment (GtkMisc *misc,
<!-- ----------------------------------------------------------------- -->
<sect1>How do I configure Tooltips in a Resource File?
<p>
-The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is not
-a GtkWidget (though a GtkObject) and as such is not attempted to match any
-widget styles.
+The tooltip's window is named "gtk-tooltips", GtkTooltips in itself is
+not a GtkWidget (though a GtkObject) and as such is not attempted to
+match any widget styles.
So, you resource file should look something like:
<verb>
NULL);
</verb></tscreen>
+<!-- ----------------------------------------------------------------- -->
+<sect1>How do I validate/limit/filter the input to a GtkEntry?
+<p>
+If you want to validate the text that a user enters into a GtkEntry
+widget you can attach to the "insert_text" signal of the entry, and
+modify the text within the callback function. The example below forces
+all characters to uppercase, and limits the range of characters to
+A-Z. Note that the entry is cast to an object of type GtkEditable,
+from which GtkEntry is derived.
+
+<tscreen><verb>
+#include <ctype.h>
+#include <gtk/gtk.h>
+
+void insert_text_handler (GtkEntry *entry,
+ const gchar *text,
+ gint length,
+ gint *position,
+ gpointer data)
+{
+ GtkEditable *editable = GTK_EDITABLE(entry);
+ int i, count=0;
+ gchar *result = g_new (gchar, length);
+
+ for (i=0; i < length; i++) {
+ if (!isalpha(text[i]))
+ continue;
+ result[count++] = islower(text[i]) ? toupper(text[i]) : text[i];
+ }
+
+ if (count > 0) {
+ gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (insert_text_handler),
+ data);
+ gtk_editable_insert_text (editable, result, count, position);
+ gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (insert_text_handler),
+ data);
+ }
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
+
+ g_free (result);
+}
+
+int main (int argc,
+ char *argv[])
+{
+ GtkWidget *window;
+ GtkWidget *entry;
+
+ gtk_init (&argc, &argv);
+
+ /* create a new window */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
+ gtk_signal_connect(GTK_OBJECT (window), "delete_event",
+ (GtkSignalFunc) gtk_exit, NULL);
+
+ entry = gtk_entry_new();
+ gtk_signal_connect(GTK_OBJECT(entry), "insert_text",
+ GTK_SIGNAL_FUNC(insert_text_handler),
+ NULL);
+ gtk_container_add(GTK_CONTAINER (window), entry);
+ gtk_widget_show(entry);
+
+ gtk_widget_show(window);
+
+ gtk_main();
+ return(0);
+}
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>How do I use horizontal scrollbars with a GtkText widget?
<p>
Notice that the response is valid for any object that inherits from the
GtkEditable class.
-Are you sure that you want to move the cursor position? Most of the time,
-while the cursor position is good, the insertion point does not match the
-cursor position. If this apply to what you really want, then you should use
-the <tt/gtk_text_set_point()/ function. If you want to set the insertion point
-at the current cursor position, use the following:
+Are you sure that you want to move the cursor position? Most of the
+time, while the cursor position is good, the insertion point does not
+match the cursor position. If this apply to what you really want, then
+you should use the <tt/gtk_text_set_point()/ function. If you want to
+set the insertion point at the current cursor position, use the
+following:
<tscreen><verb>
gtk_text_set_point(GTK_TEXT(text),
- gtk_editable_get_position(GTK_EDITABLE(text)));
+ gtk_editable_get_position(GTK_EDITABLE(text)));
</verb></tscreen>
If you want the insertion point to follow the cursor at all time, you
should probably catch the button press event, and then move the
-insertion point. Be careful : you'll have to catch it after the widget
-has changed the cursor position though. Thomas Mailund Jensen proposed the
-following code:
+insertion point. Be careful : you'll have to catch it after the widget
+has changed the cursor position though. Thomas Mailund Jensen proposed
+the following code:
<tscreen><verb>
static void
{
/* jump to cursor mark */
gtk_text_set_point (GTK_TEXT (text),
- gtk_editable_get_position (GTK_EDITABLE (text)));
+ gtk_editable_get_position (GTK_EDITABLE (text)));
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
"bar", strlen ("bar"));
<!-- ----------------------------------------------------------------- -->
<sect1>What is GDK?
<p>
-GDK is basically a wrapper around the standard Xlib function calls. If you are
-at all familiar with Xlib, a lot of the functions in GDK will require little
-or no getting used to. All functions are written to provide an way
-to access Xlib functions in an easier and slightly more intuitive manner.
-In addition, since GDK uses GLib (see below), it will be more portable
-and safer to use on multiple platforms.
+GDK is basically a wrapper around the standard Xlib function calls. If
+you are at all familiar with Xlib, a lot of the functions in GDK will
+require little or no getting used to. All functions are written to
+provide an way to access Xlib functions in an easier and slightly more
+intuitive manner. In addition, since GDK uses GLib (see below), it
+will be more portable and safer to use on multiple platforms.
<!-- Examples, anybody? I've been mulling some over. NF -->
<!-- I believe it should be better :) ED -->
<!-- Linked lists are pretty standard data structures - don't want to
over do it - TRG -->
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Memory does not seem to be released when I free the list nodes I've allocated
+<p>
+GLib tries to be "intelligent" on this special issue: it assumes that
+you are likely to reuse the objects, so caches the allocated memory.
+If you do not want to use this behavior, you'll probably want to set
+up a special allocator.
+
+To quote Tim Janik:
+<quote>
+If you have a certain portion of code that uses *lots* of GLists or
+GNodes, and you know you'd better want to release all of them after a
+short while, you'd want to use a GAllocator. Pushing an allocator into
+g_list will make all subsequent glist operations private to that
+allocator's memory pool (and thus you have to take care to pop the
+allocator again, before making any external calls):
+</quote>
+
+<tscreen><verb>
+GAllocator *allocator;
+GList *list = NULL;
+guint i;
+
+/* set a new allocation pool for GList nodes */
+allocator = g_allocator_new ("list heap", 1024);
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+for (i = 0; i < 4096; i++)
+ list = g_list_prepend (list, NULL);
+list = g_list_reverse (list);
+
+/* beware to pop allocator befor calling external functions */
+g_list_pop_allocator ();
+gtk_label_set_text (GTK_LABEL (some_label), "some text");
+
+/* and set our private glist pool again */
+g_list_push_allocator (allocator);
+
+/* do some list operations */
+g_list_free (list);
+list = NULL;
+for (i = 0; i < 4096; i++)
+ list = g_list_prepend (list, NULL);
+
+/* and back out (while freeing all of the list nodes in our pool) */
+g_list_pop_allocator ();
+g_allocator_free (allocator);
+</verb></tscreen>
+
<!-- ----------------------------------------------------------------- -->
<sect1>Why use g_print, g_malloc, g_strdup and fellow glib functions?
<p>
Thanks to Tim Janik who wrote to gtk-list: (slightly modified)
<quote>
-Regarding g_malloc(), g_free() and siblings, these functions are much safer
-than their libc equivalents. For example, g_free() just returns if called
-with NULL. Also, if USE_DMALLOC is defined, the definition for these
-functions changes (in glib.h) to use MALLOC(), FREE() etc... If MEM_PROFILE
-or MEM_CHECK are defined, there are even small statistics made counting
-the used block sizes (shown by g_mem_profile() / g_mem_check()).
-<P>
+Regarding g_malloc(), g_free() and siblings, these functions are much
+safer than their libc equivalents. For example, g_free() just returns
+if called with NULL. Also, if USE_DMALLOC is defined, the definition
+for these functions changes (in glib.h) to use MALLOC(), FREE() etc...
+If MEM_PROFILE or MEM_CHECK are defined, there are even small
+statistics made counting the used block sizes (shown by
+g_mem_profile() / g_mem_check()).
+<p>
Considering the fact that glib provides an interface for memory chunks
to save space if you have lots of blocks that are always the same size
and to mark them ALLOC_ONLY if needed, it is just straight forward to
create a small saver (debug able) wrapper around the normal malloc/free
stuff as well - just like gdk covers Xlib. ;)
-<P>
+<p>
Using g_error() and g_warning() inside of applications like the GIMP
that fully rely on gtk even gives the opportunity to pop up a window
showing the messages inside of a gtk window with your own handler
You need to understand that the scanner will parse its input and
tokenize it, it is up to you to interpret these tokens, not define
-their types before they get parsed, e.g. watch gscanner parse a string:
+their types before they get parsed, e.g. watch gscanner parse a
+string:
<verb>
"hi i am 17"
<htmlurl url="mailto:amundson@gimp.org"
name="<amundson@gimp.org>"> who continues to provide support.
-Contributions should be sent to Tony Gale <htmlurl url="mailto:gale@gtk.org"
-name="<gale@gtk.org>">
+Contributions should be sent to Tony Gale <htmlurl
+url="mailto:gale@gtk.org" name="<gale@gtk.org>">
The GTK+ FAQ is Copyright (C) 1997-2000 by Shawn T. Amundson,
Tony Gale, Emmanuel Deloget and Nathan Froyd.