Las etiquetas se usan mucho en GTK y son bastante simples de manejar. No pueden emitir señales ya que no tienen ventanas X window asociadas. Si se desea capturar señales se debe usar el widget EventBox.
Para crear una nueva etiqueta se usa:
GtkWidget *gtk_label_new( char *str );
El único argumento es la cadena de texto que se quiere mostrar.
Para cambiarla después de que haya sido creada se usa:
void gtk_label_set( GtkLabel *label,
char *str );
En este caso el primer argumento es la etiqueta ya creada (cambiado su tipo mediante la macro GTK_LABEL()) y el segundo es la nueva cadena. El espacio que necesite la nueva etiqueta se ajustará automáticamente, si es necesario.
Para obtener el estado de la cadena en un momento dado existe la función:
void gtk_label_get( GtkLabel *label,
char **str );
El primer argumento es la etiqueta, mientras que el segundo es el
valor devuelto para la cadena.
Estos widgets son las pequeñas etiquetas que texto que aparecen cuando se sitúa el puntero del ratón sobre un botón u otro widget durante algunos segundos. Son bastante fáciles de usar, así que no se dára ningún ejemplo. Si quiere ver algún ejemplo se recomienda leer el programa testgtk.c que acompaña a GTK.
Algunos widgets (como la etiqueta) no pueden llevar asociado un tooltip.
Para cada función sólo hay que hacer una llamada para conseguir
un tooltip. El objeto GtkTooltip
que devuelve la siguiente
función puede ser usado para crear múltiples widgets.
GtkTooltips *gtk_tooltips_new( void );
Una vez que el tooltip ha sido creado (y el widget sobre el que se quiere usar) simplemente hay que usar la siguiente llamada para pegarlo:
void gtk_tooltips_set_tip( GtkTooltips *tooltips,
GtkWidget *widget,
const gchar *tip_text,
const gchar *tip_private );
El primer argumento es el tooltip que ya ha creado, seguido del widget al que se desea asociar el tooltip, el tercero es el texto que se quiere que aparezca y el último es una cadena de texto que puede ser usada como un identificador cuando se usa GtkTipsQuery para desarollar ayuda sensible al contexto. Por ahora conviene dejarlo como NULL.
Veamos un ejemplo:
GtkTooltips *tooltips;
GtkWidget *button;
...
tooltips = gtk_tooltips_new ();
button = gtk_button_new_with_label ("button 1");
...
gtk_tooltips_set_tip (tooltips, button, "This is button 1", NULL);
Existen otras funciones que pueden ser usadas con los tooltips. Sólamente vamos a enumerlarlas añadiendo una pequeña descripción de que hace cada una.
void gtk_tooltips_enable( GtkTooltips *tooltips );
Permite que funcionen un conjunto de tooltips
void gtk_tooltips_disable( GtkTooltips *tooltips );
Oculta un conjunto de tooltips para que no pueda ser mostrado.
void gtk_tooltips_set_delay( GtkTooltips *tooltips,
gint delay );
Establece cuantos milisegundos tiene que estar el puntero sobre el widget para que aparezca el tooltip. Por defecto se usan 1000 milisegundos (1 segundo).
void gtk_tooltips_set_colors( GtkTooltips *tooltips,
GdkColor *background,
GdkColor *foreground );
Establece el color del texto y del fondo del tooltip. No se como se especifica el color.
Estas barras se usan para mostrar el estado de un proceso. Son bastante fáciles de usar, tal y como se verá en los ejemplos siguientes. La primera llamada sirve para crear la barra de progreso:
GtkWidget *gtk_progress_bar_new( void );
Como la barra ya ha sido creada ya puede ser usada:
void gtk_progress_bar_update( GtkProgressBar *pbar,
gfloat percentage );
El primer argumento es la barra que se quiere manejar, el segundo es tanto por ciento que ha sido `completado' (indica cuanto ha sido llenada la barra y oscila entre 0-100%). El valor que se le tiene que pasar oscila entre 0 y 1.
Las barras de progreso se usan con otras funciones como los tiempos de espera (timeouts), sección Tiempos de espera, E/S (I/O) y funciones ociosas (idle)) para crear la ilusión de la multitarea. Todas usan la función gtk_progress_bar_update de la misma manera.
Estudiemos un ejemplo de barras de progreso actualizada usando tiempos de espera. También se muestra como se debe reestablecer una barra.
/* comienzo del programa-ejemplo progressbar.c */
#include <gtk/gtk.h>
static int ptimer = 0;
int pstat = TRUE;
/* Esta función incrementa y actualiza la barra. En el caso de que
* pstat sea FALSE la restablece a cero */
gint progress (gpointer data)
{
gfloat pvalue;
/* valor actual de la barra*/
pvalue = GTK_PROGRESS_BAR (data)->percentage;
if ((pvalue >= 1.0) || (pstat == FALSE)) {
pvalue = 0.0;
pstat = TRUE;
}
pvalue += 0.01;
gtk_progress_bar_update (GTK_PROGRESS_BAR (data), pvalue);
return TRUE;
}
/* Esta función indica que la barra debe ser restablecida */
void progress_r (void)
{
pstat = FALSE;
}
void destroy (GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *label;
GtkWidget *table;
GtkWidget *pbar;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (destroy), NULL);
gtk_container_border_width (GTK_CONTAINER (window), 10);
table = gtk_table_new(3,2,TRUE);
gtk_container_add (GTK_CONTAINER (window), table);
label = gtk_label_new ("Progress Bar Example");
gtk_table_attach_defaults(GTK_TABLE(table), label, 0,2,0,1);
gtk_widget_show(label);
/* Crear una nueva barra de progreso, empaquetarla en la tabla y
* mostrarla */
pbar = gtk_progress_bar_new ();
gtk_table_attach_defaults(GTK_TABLE(table), pbar, 0,2,1,2);
gtk_widget_show (pbar);
ptimer = gtk_timeout_add (100, progress, pbar);
/* Mediante este botón se restablece la barra */
button = gtk_button_new_with_label ("Reset");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (progress_r), NULL);
gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,2,3);
gtk_widget_show(button);
button = gtk_button_new_with_label ("Cancel");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (destroy), NULL);
gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,2,3);
gtk_widget_show (button);
gtk_widget_show(table);
gtk_widget_show(window);
gtk_main ();
return 0;
}
/* final del ejemplo */
Para manejar las barras de progreso hay que llevar a cabo cuatro pasos diferentes. Ahora vamos a estudiar cada uno a partir del ejemplo.
pbar = gtk_progress_bar_new ();
Creamos una nueva barra llamada pbar.
ptimer = gtk_timeout_add (100, progress, pbar);
Usamos un timeout para que el intervalo de tiempo sea constante. Los timeouts no son necesarios para usar barras de progreso.
pvalue = GTK_PROGRESS_BAR (data)->percentage;
Asignamos el valor actual del porcentaje a pvalue.
gtk_progress_bar_update (GTK_PROGRESS_BAR (data), pvalue);
Por último actualizamos la barra con el valor de pvalue. Eso es todo lo que hay que saber a cerca de las barras de progreso.
El widget de cuadro de diálogo es bastante simple, sólo es una ventana con algunas cosas ya preempaquetadas. Su estructura es la siguiente:
struct GtkDialog
{
GtkWindow window;
GtkWidget *vbox;
GtkWidget *action_area;
};
Simplemente se crea una ventana en la cual se empaqueta una vbox, un separador y una hbox llamada ``action_area''.
Este tipo de widgets puede ser usado como mensages pop-up (pequeñas ventanas con texto en su interior que aparecen cuando el usuario hace algo y queremos informarle de alguna cosa) y otras cosas parecidas. Su manejo desde el punto de vista del programador es bastante fácil, sólo hay que usar una función:
GtkWidget *gtk_dialog_new( void );
Para crear un nuevo cuadro de diálogo hay que llamar a:
GtkWidget *window;
window = gtk_dialog_new ();
Una vez que el cuadro ha sido creado sólo hay que usarlo. Por ejemplo para empaquetar un botón en la action_area escribiríamos algo así:
button = ...
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button,
TRUE, TRUE, 0);
gtk_widget_show (button);
Otra cosa que nos puede interesar es empaquetar una etiqueta en la vbox:
label = gtk_label_new ("Dialogs are groovy");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), label, TRUE,
TRUE, 0);
gtk_widget_show (label);
Otros ejemplo posible es poner dos botones en el action_area (uno para cancelar y el otro para permitir algo) junto con una etiqueta en la vbox el usuario puede seleccionar lo que quiera.
Si se precisa algo más complejo siempre se puede empaquetar otro widget en cualquiera de las cajas (p.j. una tabla en una vbox).
Los pixmaps son estructuras de datos que contienen dibujos. Estos pueden ser usados en diferentes lugares, pero los iconos y los cursores son los más comunes. Un bitmap es un pixmap que sólo tiene dos colores.
Para usar un pixmap en GTK primero tiene que construir una estructura del tipo GdkPixmap usando rutinas de GDK. Los pixmaps se pueden crear usando datos que se encuentren en la memoria o en un archivo. Veremos con detalle cada una de las dos posibilidades.
GdkPixmap *gdk_bitmap_create_from_data( GdkWindow *window,
gchar *data,
gint width,
gint height );
Esta rutina se utiliza para crear un bitmap a partir de datos almacenados en la memoria. Cada bit de información indica si el pixel luce o no. Tanto la altura como la anchura estan expresadas en pixels. El puntero del tipo GdkWindow indica la ventana en cuestión, ya que los pixmaps sólo tienen sentido dentro de la pantalla en la que van a ser mostrados.
GdkPixmap *gdk_pixmap_create_from_data( GdkWindow *window,
gchar *data,
gint width,
gint height,
gint depth,
GdkColor *fg,
GdkColor *bg );
Con esto creamos un pixmap con la profundidad (número de
colores) especificada en los datos del bitmap. Los valores
fg
y bg
son los colores del frente y del fondo
respectivamente.
GdkPixmap *gdk_pixmap_create_from_xpm( GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
const gchar *filename );
El formato XPM es una representacion de los pixmaps para el
sistema X Window. Es bastante popular y existen muchos programas para
crear imágenes en este formato. El archivo especificado mediante
filename
debe contener una imagen en ese formato para que sea
cargada en la estructura. La máscara especifica que bits son
opacos. Todos los demás bits se colorean usando el color
especificado en transparent_color
. Más adelante veremos un
ejemplo.
GdkPixmap *gdk_pixmap_create_from_xpm_d( GdkWindow *window,
GdkBitmap **mask,
GdkColor *transparent_color,
gchar **data );
Se puede incorporar Imágenes pequeñas dentro de un programa en formato XPM. Un pixmap se crea usando esta información, en lugar de leerla de un archivo. Un ejemplo sería:
/* XPM */
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
Cuando hayamos acabado de usar un pixmap y no lo vayamos a usar durante un tiempo suele ser conveniente liberar el recurso mediante gdk_pixmap_unref(). (Los pixmaps deben ser considerados recursos preciosos).
Una vez que hemos creado el pixmap lo podemos mostrar como un widget GTK. Primero tenemos que crear un widget pixmap que contenga un pixmap GDK. Esto se hace usando:
GtkWidget *gtk_pixmap_new( GdkPixmap *pixmap,
GdkBitmap *mask );
Las otras funciones del widget pixmap son:
guint gtk_pixmap_get_type( void );
void gtk_pixmap_set( GtkPixmap *pixmap,
GdkPixmap *val,
GdkBitmap *mask );
void gtk_pixmap_get( GtkPixmap *pixmap,
GdkPixmap **val,
GdkBitmap **mask);
La función gtk_pixmap_set se usa para cambiar los datos del
pixmap que el widget está manejando en ese
momento. val
es el pixmap creado usando GDK.
El ejemplo siguiente usa un pixmap en un botón:
/* comienzo del ejemplo pixmap.c */
#include <gtk/gtk.h>
/* Datos en formato XPM del icono de apertura de archivo */
static const char * xpm_data[] = {
"16 16 3 1",
" c None",
". c #000000000000",
"X c #FFFFFFFFFFFF",
" ",
" ...... ",
" .XXX.X. ",
" .XXX.XX. ",
" .XXX.XXX. ",
" .XXX..... ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" .XXXXXXX. ",
" ......... ",
" ",
" "};
/* Cuando se llama a esta función (usando signal delete_event) se
* termina la aplicación*/
void close_application( GtkWidget *widget, GdkEvent *event, gpointer data ) {
gtk_main_quit();
}
/* Al presionar el botón aparece el mensaje */
void button_clicked( GtkWidget *widget, gpointer data ) {
printf( "button clicked\n" );
}
int main( int argc, char *argv[] )
{
GtkWidget *window, *pixmapwid, *button;
GdkPixmap *pixmap;
GdkBitmap *mask;
GtkStyle *style;
/* Creamos la ventana principal y relacionamos la señal
* delete_event con acabar el programa.*/
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_signal_connect( GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (close_application), NULL );
gtk_container_border_width( GTK_CONTAINER (window), 10 );
gtk_widget_show( window );
/* Ahora para el pixmap de gdk */
style = gtk_widget_get_style( window );
pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_data );
/* Un pixmap widget que contendrá al pixmap */
pixmapwid = gtk_pixmap_new( pixmap, mask );
gtk_widget_show( pixmapwid );
/* Un botón para contener al pixmap */
button = gtk_button_new();
gtk_container_add( GTK_CONTAINER(button), pixmapwid );
gtk_container_add( GTK_CONTAINER(window), button );
gtk_widget_show( button );
gtk_signal_connect( GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(button_clicked), NULL );
/* mostramos la ventana */
gtk_main ();
return 0;
}
/* final del ejemplo */
Para cargar un archivo llamado icon0.xpm con la información XPM (que se encuentra en en directorio actual) habríamos usado:
/* cargar un pixmap desde un fichero */
pixmap = gdk_pixmap_create_from_xpm( window->window, &mask,
&style->bg[GTK_STATE_NORMAL],
"./icon0.xpm" );
pixmapwid = gtk_pixmap_new( pixmap, mask );
gtk_widget_show( pixmapwid );
gtk_container_add( GTK_CONTAINER(window), pixmapwid );
Una desventaja de los pixmaps es que la imagen mostrada siempre es rectangular (independientemente de como sea la imagen en sí). Si queremos usar imágenes con otras formas debemos usar ventanas con forma (shaped windows).
Este tipo de ventanas son pixmaps en los que el fondo es transparente. Así cuando la imagen del fondo tiene muchos colores no los sobreescribimos con el borde de nuestro icono. El ejemplo siguiente muestra la imagen de una carretilla en el escritorio.
/* comienzo del ejemplo carretilla wheelbarrow.c */
#include <gtk/gtk.h>
/* XPM */
static char * WheelbarrowFull_xpm[] = {
"48 48 64 1",
" c None",
". c #DF7DCF3CC71B",
"X c #965875D669A6",
"o c #71C671C671C6",
"O c #A699A289A699",
"+ c #965892489658",
"@ c #8E38410330C2",
"# c #D75C7DF769A6",
"$ c #F7DECF3CC71B",
"% c #96588A288E38",
"& c #A69992489E79",
"* c #8E3886178E38",
"= c #104008200820",
"- c #596510401040",
"; c #C71B30C230C2",
": c #C71B9A699658",
"> c #618561856185",
", c #20811C712081",
"< c #104000000000",
"1 c #861720812081",
"2 c #DF7D4D344103",
"3 c #79E769A671C6",
"4 c #861782078617",
"5 c #41033CF34103",
"6 c #000000000000",
"7 c #49241C711040",
"8 c #492445144924",
"9 c #082008200820",
"0 c #69A618611861",
"q c #B6DA71C65144",
"w c #410330C238E3",
"e c #CF3CBAEAB6DA",
"r c #71C6451430C2",
"t c #EFBEDB6CD75C",
"y c #28A208200820",
"u c #186110401040",
"i c #596528A21861",
"p c #71C661855965",
"a c #A69996589658",
"s c #30C228A230C2",
"d c #BEFBA289AEBA",
"f c #596545145144",
"g c #30C230C230C2",
"h c #8E3882078617",
"j c #208118612081",
"k c #38E30C300820",
"l c #30C2208128A2",
"z c #38E328A238E3",
"x c #514438E34924",
"c c #618555555965",
"v c #30C2208130C2",
"b c #38E328A230C2",
"n c #28A228A228A2",
"m c #41032CB228A2",
"M c #104010401040",
"N c #492438E34103",
"B c #28A2208128A2",
"V c #A699596538E3",
"C c #30C21C711040",
"Z c #30C218611040",
"A c #965865955965",
"S c #618534D32081",
"D c #38E31C711040",
"F c #082000000820",
" ",
" .XoO ",
" +@#$%o& ",
" *=-;#::o+ ",
" >,<12#:34 ",
" 45671#:X3 ",
" +89<02qwo ",
"e* >,67;ro ",
"ty> 459@>+&& ",
"$2u+ ><ipas8* ",
"%$;=* *3:.Xa.dfg> ",
"Oh$;ya *3d.a8j,Xe.d3g8+ ",
" Oh$;ka *3d$a8lz,,xxc:.e3g54 ",
" Oh$;kO *pd$%svbzz,sxxxxfX..&wn> ",
" Oh$@mO *3dthwlsslszjzxxxxxxx3:td8M4 ",
" Oh$@g& *3d$XNlvvvlllm,mNwxxxxxxxfa.:,B* ",
" Oh$@,Od.czlllllzlmmqV@V#V@fxxxxxxxf:%j5& ",
" Oh$1hd5lllslllCCZrV#r#:#2AxxxxxxxxxcdwM* ",
" OXq6c.%8vvvllZZiqqApA:mq:Xxcpcxxxxxfdc9* ",
" 2r<6gde3bllZZrVi7S@SV77A::qApxxxxxxfdcM ",
" :,q-6MN.dfmZZrrSS:#riirDSAX@Af5xxxxxfevo",
" +A26jguXtAZZZC7iDiCCrVVii7Cmmmxxxxxx%3g",
" *#16jszN..3DZZZZrCVSA2rZrV7Dmmwxxxx&en",
" p2yFvzssXe:fCZZCiiD7iiZDiDSSZwwxx8e*>",
" OA1<jzxwwc:$d%NDZZZZCCCZCCZZCmxxfd.B ",
" 3206Bwxxszx%et.eaAp77m77mmmf3&eeeg* ",
" @26MvzxNzvlbwfpdettttttttttt.c,n& ",
" *;16=lsNwwNwgsvslbwwvccc3pcfu<o ",
" p;<69BvwwsszslllbBlllllllu<5+ ",
" OS0y6FBlvvvzvzss,u=Blllj=54 ",
" c1-699Blvlllllu7k96MMMg4 ",
" *10y8n6FjvllllB<166668 ",
" S-kg+>666<M<996-y6n<8* ",
" p71=4 m69996kD8Z-66698&& ",
" &i0ycm6n4 ogk17,0<6666g ",
" N-k-<> >=01-kuu666> ",
" ,6ky& &46-10ul,66, ",
" Ou0<> o66y<ulw<66& ",
" *kk5 >66By7=xu664 ",
" <<M4 466lj<Mxu66o ",
" *>> +66uv,zN666* ",
" 566,xxj669 ",
" 4666FF666> ",
" >966666M ",
" oM6668+ ",
" *4 ",
" ",
" "};
void close_application( GtkWidget *widget, GdkEvent *event, gpointer data ) {
gtk_main_quit();
}
int main (int argc, char *argv[])
{
GtkWidget *window, *pixmap, *fixed;
GdkPixmap *gdk_pixmap;
GdkBitmap *mask;
GtkStyle *style;
GdkGC *gc;
/* Creamos la ventana principal y relacionamos la señal
* delete_event para terminar la aplicación. Conviene destacar
* que la ventana no tendrá título puesto que es popup.*/
gtk_init (&argc, &argv);
window = gtk_window_new( GTK_WINDOW_POPUP );
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (close_application), NULL);
gtk_widget_show (window);
style = gtk_widget_get_default_style();
gc = style->black_gc;
gdk_pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
&style->bg[GTK_STATE_NORMAL],
WheelbarrowFull_xpm );
pixmap = gtk_pixmap_new( gdk_pixmap, mask );
gtk_widget_show( pixmap );
fixed = gtk_fixed_new();
gtk_widget_set_usize( fixed, 200, 200 );
gtk_fixed_put( GTK_FIXED(fixed), pixmap, 0, 0 );
gtk_container_add( GTK_CONTAINER(window), fixed );
gtk_widget_show( fixed );
/* Con esto cubrimos todo menos la imagen */
gtk_widget_shape_combine_mask( window, mask, 0, 0 );
/* mostramos la ventana */
gtk_widget_set_uposition( window, 20, 400 );
gtk_widget_show( window );
gtk_main ();
return 0;
}
/* final del ejemplo */
Para que la carretilla sea más realista podríamos relacionar la pulsación del botón con que haga algo. Con las líneas siguientes la pulsación del botón hace que se acabe el programa.
gtk_widget_set_events( window,
gtk_widget_get_events( window ) |
GDK_BUTTON_PRESS_MASK );
gtk_signal_connect( GTK_OBJECT(window), "button_press_event",
GTK_SIGNAL_FUNC(close_application), NULL );
Las reglas son usadas para indicar la posición del puntero del ratón en una ventana dada. Una ventana puede tener una regla vertical a lo largo de su alto y una horizontal a lo largo de su ancho. Un pequeño indicador triangular muestra la relación entre el puntero del ratón y la regla.
Las reglas (horizontales y verticales) se crean usando:
GtkWidget *gtk_hruler_new( void ); /* horizontal */
GtkWidget *gtk_vruler_new( void ); /* vertical */
Las unidades de la regla pueden ser pixels, pulgadas o centímetros (GKD_PIXELS, GDK_INCHES, GDK_CENTIMETRES). Esto se hace usando:
void gtk_ruler_set_metric( GtkRuler *ruler,
GtkMetricType metric );
El valor por defecto es GTK_PIXELS.
gtk_ruler_set_metric( GTK_RULER(ruler), GTK_PIXELS );
Otra característica importante de las reglas es cómo mostrar las unidades de escala y la posicion inicial dónde se situa el indicador. Todo esto se consigue mediante:
void gtk_ruler_set_range( GtkRuler *ruler,
gfloat lower,
gfloat upper,
gfloat position,
gfloat max_size );
Los argumentos lower
(valor más bajo) y upper
(más
alto) delimitan la extensión de la regla. El argumento
max_size
es el número más alto que será mostrado. Como
es lógico position
define la posición inicial del indicador
dentro de la regla.
Una regla vertical puede puede llegar a ser de 800 pixels:
gtk_ruler_set_range( GTK_RULER(vruler), 0, 800, 0, 800);
Las marcas dentro de la regla oscilarán entre 0 y 800 con una periodicidad de 100. Si queremos que varíe entre 7 y 16 debemos usar:
gtk_ruler_set_range( GTK_RULER(vruler), 7, 16, 0, 20);
El indicador de la regla es un pequeño triángulo que señala la posición del puntero con relación a la regla. Si la regla debe seguir al puntero del ratón la señal motion_notify_event debe estar conectada con el motion_notify_event de la regla. Para seguir todos los movimientos dentro de una ventana conviene usar:
#define EVENT_METHOD(i, x) GTK_WIDGET_CLASS(GTK_OBJECT(i)->klass)->x
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
(GtkSignalFunc)EVENT_METHOD(ruler, motion_notify_event),
GTK_OBJECT(ruler) );
El siguiente ejemplo crea una zona de dibujo con una regla horizontal y otra vertical. El tamaño de la zona de dibujo es de 600 x 400 pixels. La regla horizontal oscila entre 7 y 13 con marcas cada 100 pixels, mientras que la vertical va desde 0 a 400 con separaciones cada 100. La zona de dibujo y las reglas se sitúan usando una tabla.
/* comienzo del ejemplo rulers.c */
#include <gtk/gtk.h>
#define EVENT_METHOD(i, x) GTK_WIDGET_CLASS(GTK_OBJECT(i)->klass)->x
#define XSIZE 600
#define YSIZE 400
/* Esta rutina toma el control cuando se pulsa el botón close
*/
void close_application( GtkWidget *widget, GdkEvent *event, gpointer data ) {
gtk_main_quit();
}
int main( int argc, char *argv[] ) {
GtkWidget *window, *table, *area, *hrule, *vrule;
gtk_init( &argc, &argv );
window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC( close_application ), NULL);
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* creación de la tabla donde pondremos las reglas y la zona de
* dibujo */
table = gtk_table_new( 3, 2, FALSE );
gtk_container_add( GTK_CONTAINER(window), table );
area = gtk_drawing_area_new();
gtk_drawing_area_size( (GtkDrawingArea *)area, XSIZE, YSIZE );
gtk_table_attach( GTK_TABLE(table), area, 1, 2, 1, 2,
GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_events( area, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK );
/* La regla horizontal está arriba. Cuando el ratón se mueve
* a lo largo de la zona de dibujo el controlador de eventos de la
* regla recibe motion_notify_event. */
hrule = gtk_hruler_new();
gtk_ruler_set_metric( GTK_RULER(hrule), GTK_PIXELS );
gtk_ruler_set_range( GTK_RULER(hrule), 7, 13, 0, 20 );
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
(GtkSignalFunc)EVENT_METHOD(hrule, motion_notify_event),
GTK_OBJECT(hrule) );
/* GTK_WIDGET_CLASS(GTK_OBJECT(hrule)->klass)->motion_notify_event, */
gtk_table_attach( GTK_TABLE(table), hrule, 1, 2, 0, 1,
GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0 );
/* la zona de dibujo el controlador de eventos de la regla recibe
* motion_notify_event. */
vrule = gtk_vruler_new();
gtk_ruler_set_metric( GTK_RULER(vrule), GTK_PIXELS );
gtk_ruler_set_range( GTK_RULER(vrule), 0, YSIZE, 10, YSIZE );
gtk_signal_connect_object( GTK_OBJECT(area), "motion_notify_event",
(GtkSignalFunc)
GTK_WIDGET_CLASS(GTK_OBJECT(vrule)->klass)->motion_notify_event,
GTK_OBJECT(vrule) );
gtk_table_attach( GTK_TABLE(table), vrule, 0, 1, 1, 2,
GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0 );
/* mostramos todo */
gtk_widget_show( area );
gtk_widget_show( hrule );
gtk_widget_show( vrule );
gtk_widget_show( table );
gtk_widget_show( window );
gtk_main();
return 0;
}
/* final del ejemplo */
Las barras de estado son widgets usados para mostrar un mensaje. Todo aquello que haya sido mostrado se guarda en una pila, con lo que es muy fácil repetir el último mensaje.
Para permitir que diferentes partes del programa usen la misma barra de estado éstas usan Identificadores por Contexto (Context Identifiers) para identificar a los `usuarios'. El mensaje que está en lo alto de la pila será el siguiente en mostrarse, sin importar el contexto en el que se esté. Los mensajes se almacenan en el orden el último en entrar es el primero en salir, y el Identificador por Contexto no influye en este orden.
Las barras de estado se crean con una llamada a:
GtkWidget *gtk_statusbar_new( void );
Se pide un nuevo Identificador por Contexto con una pequeña descripción textual del contexto y una llamada a la función:
guint gtk_statusbar_get_context_id( GtkStatusbar *statusbar,
const gchar *context_description );
Hay tres funciones que pueden manipular las barras de estado:
guint gtk_statusbar_push( GtkStatusbar *statusbar,
guint context_id,
gchar *text );
void gtk_statusbar_pop( GtkStatusbar *statusbar)
guint context_id );
void gtk_statusbar_remove( GtkStatusbar *statusbar,
guint context_id,
guint message_id );
La primera, gtk_statusbar_push
, se utiliza para añadir un nuevo
mensaje a la barra de estado. Devuelve un Identificador de Mensaje, que
podemos pasarle más tarde a la función gtk_statusbar_remove
para eliminar el mensaje con los Identificadores de Contexto y de
Mensaje que hay en la pila de barras de estado.
La función gtk_statusbar_pop elimina el mensaje que se encuentra más alto en pila y que contiene el Identificador por Contexto especificado.
El ejemplo siguiente crea una barra de estado y dos botones, uno para meter un elemento en la barra y el otro para sacar el último elemento introducido.
/* Principio del ejemplo de barras de estado statusbar.c */
#include <gtk/gtk.h>
#include <glib.h>
GtkWidget *status_bar;
void push_item (GtkWidget *widget, gpointer data)
{
static int count = 1;
char buff[20];
g_snprintf(buff, 20, "Item %d", count++);
gtk_statusbar_push( GTK_STATUSBAR(status_bar), (guint) &data, buff);
return;
}
void pop_item (GtkWidget *widget, gpointer data)
{
gtk_statusbar_pop( GTK_STATUSBAR(status_bar), (guint) &data );
return;
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *button;
int context_id;
gtk_init (&argc, &argv);
/* crear una nueva ventana */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize( GTK_WIDGET (window), 200, 100);
gtk_window_set_title(GTK_WINDOW (window), "GTK Statusbar Example");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) gtk_exit, NULL);
vbox = gtk_vbox_new(FALSE, 1);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
status_bar = gtk_statusbar_new();
gtk_box_pack_start (GTK_BOX (vbox), status_bar, TRUE, TRUE, 0);
gtk_widget_show (status_bar);
context_id = gtk_statusbar_get_context_id( GTK_STATUSBAR(status_bar), "Statusbar example");
button = gtk_button_new_with_label("push item");
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC (push_item), &context_id);
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 2);
gtk_widget_show(button);
button = gtk_button_new_with_label("pop last item");
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC (pop_item), &context_id);
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 2);
gtk_widget_show(button);
/* siempre mostramos la ventana en el último paso para que todo se
* dibuje en la pantalla de un golpe. */
gtk_widget_show(window);
gtk_main ();
return 0;
}
/* Fin del ejemplo */
El widget Entry permite mostrar e introducir texto en una línea de un cuadro de diálogo. El texto se puede poner con llamadas a funciones que permiten reemplazar, preañadir o añadir el texto al contenido actual del widget Entry.
Hay dos funciones para crear widget Entry:
GtkWidget *gtk_entry_new( void );
GtkWidget *gtk_entry_new_with_max_length( guint16 max );
La primera sirve para crear un nuevo widget Entry, mientras que la segunda crea el widget y además establece un límite en la longitud del texto que irá en el mismo.
hay varias funciones que sirven para alterar el que texto que se está en el widget Entry.
void gtk_entry_set_text( GtkEntry *entry,
const gchar *text );
void gtk_entry_append_text( GtkEntry *entry,
const gchar *text );
void gtk_entry_prepend_text( GtkEntry *entry,
const gchar *text );
La función gtk_entry_set_text
cambia el contenido actual del
widget Entry. Las funciones gtk_entry_append_text
y
gtk_entry_prepend_text
permiten añadir o preañadir texto.
Las función siguientes permiten decir donde poner el punto de inserción.
void gtk_entry_set_position( GtkEntry *entry,
gint position );
Se pueden obtener los contenidos del widget llamando a la función que se describe a continuación. Obtener los contenidos del widget puede ser útil en las funciones de llamada descritas más adelante.
gchar *gtk_entry_get_text( GtkEntry *entry );
Si quiere impedir que alguien cambie el contenido del widget escribiendo en él, utilice la función
void gtk_entry_set_editable( GtkEntry *entry,
gboolean editable );
Esta función permite camiar el estado de edición de un widget Entry,
siendo el argumento editable
TRUE o FALSE.
Si estamos utilizando el widget Entry en un sitio donde no queremos que el texto que se introduce sea visible, como por ejemplo cuando estamos introduciendo una clave, podemos utilizar la función siguiente, que también admite como argumento una bandera booleana.
void gtk_entry_set_visibility( GtkEntry *entry,
gboolean visible );
Se puede seleccionar una región del texto utilizando la siguiente función. Esta función se puede utilizar después de poner algún texto por defecto en el widget, haciéndole fácil al usuario eliminar este texto.
void gtk_entry_select_region( GtkEntry *entry,
gint start,
gint end );
Si queremos saber el momento en el que el usuario ha introducido el texto,
podemos conectar con las señales activate
o changed
. activate
se activa cuando el usuario aprieta la tecla enter en el widget.
changed
se activa cuando cambia algo del texto, p.e. cuando se introduce
o se elimina algún carácter.
/* inicio-ejemplo entry entry.c */
#include <gtk/gtk.h>
void enter_callback(GtkWidget *widget, GtkWidget *entry)
{
gchar *entry_text;
entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
printf("Entry contents: %s\n", entry_text);
}
void entry_toggle_editable (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_editable(GTK_ENTRY(entry),
GTK_TOGGLE_BUTTON(checkbutton)->active);
}
void entry_toggle_visibility (GtkWidget *checkbutton,
GtkWidget *entry)
{
gtk_entry_set_visibility(GTK_ENTRY(entry),
GTK_TOGGLE_BUTTON(checkbutton)->active);
}
int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox, *hbox;
GtkWidget *entry;
GtkWidget *button;
GtkWidget *check;
gtk_init (&argc, &argv);
/* crear una nueva ventana */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize( GTK_WIDGET (window), 200, 100);
gtk_window_set_title(GTK_WINDOW (window), "GTK Entry");
gtk_signal_connect(GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) gtk_exit, NULL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
entry = gtk_entry_new_with_max_length (50);
gtk_signal_connect(GTK_OBJECT(entry), "activate",
GTK_SIGNAL_FUNC(enter_callback),
entry);
gtk_entry_set_text (GTK_ENTRY (entry), "hello");
gtk_entry_append_text (GTK_ENTRY (entry), " world");
gtk_entry_select_region (GTK_ENTRY (entry),
0, GTK_ENTRY(entry)->text_length);
gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
gtk_widget_show (entry);
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (vbox), hbox);
gtk_widget_show (hbox);
check = gtk_check_button_new_with_label("Editable");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(check), "toggled",
GTK_SIGNAL_FUNC(entry_toggle_editable), entry);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), TRUE);
gtk_widget_show (check);
check = gtk_check_button_new_with_label("Visible");
gtk_box_pack_start (GTK_BOX (hbox), check, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT(check), "toggled",
GTK_SIGNAL_FUNC(entry_toggle_visibility), entry);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(check), TRUE);
gtk_widget_show (check);
button = gtk_button_new_with_label ("Close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(gtk_exit),
GTK_OBJECT (window));
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show(window);
gtk_main();
return(0);
}
/* fin del ejemplo */
El widget selección de color, nos permite (¡sorpresa!) la selección interactiva de colores. Este widget compuesto le permite al usuario seleccionar un color manipulando los tripletes RGB (rojo, verde y azul) y HSV (tono, saturación, valor). Para conseguirlo puede ajustar cada variable mediante las regletas o introduciendo directamente el valor deseado. También puede pinchar en la rueda de colores y seleccionar así el color deseado. También se puede establecer, opcionalmente, la transparencia del color.
El widget de selección de color emite (por ahora) sólo una señal,
color_changed
, que se emite cuando cambia el color seleccionado,
ya sea mediante un cambio que haga el usuario o median el resultado
de una llamada a la función gtk_color_selection_set_color()
.
Echémosle un vistazo a lo que nos ofrece el widget de selección de color.
El widget tiene dos ``sabores'' diferentes; gtk_color_selection
y gtk_color_selection_dialog
:
GtkWidget *gtk_color_selection_new( void );
Probablemente no utilizará este constructor directamente. Crea un widget GtkColorSelection huérfano al que le tendrá que asignarle un padre. El widget GtkColorSelection está heredado del widget GtkVBox.
GtkWidget *gtk_color_selection_dialog_new( const gchar *title );
Éste es el constructor del cuadro de selección de color más común. Crea un
GtkColorSelectionDialog
, heredado de un GtkDialog
. Consiste en un
GtkFrame
con un GtkColorSelection
, un GtkHSeparator
y un
GtkHBox
con tres botones, ``Aceptar'', ``Cancelar'' y ``Ayuda''.
Puede utilizar estos botones accediendo a los widgets ok_button
,
cancel_button
y help_button
de la estructura GtkColorSelectionDialog,
(es decir GTK_COLOR_SELECTION_DIALOG(colorseldialog)->ok_button).
void gtk_color_selection_set_update_policy( GtkColorSelection *colorsel,
GtkUpdateType policy );
Esta función se utiliza para indicar la política de actuación. La política
por defecto es GTK_UPDATE_CONTINUOUS
que significa que el color
seleccionado se actualiza continuamente cuando el usuario arrastra la barra
o selecciona con el ratón un color de la rueda de colores. Si tiene problemas
de rendimiento, puede poner la política GTK_UPDATE_DISCONTINUOUS
o
GTK_UPDATE_DELAYED
.
void gtk_color_selection_set_opacity( GtkColorSelection *colorsel,
gint use_opacity );
El widget de selección de color admite el ajuste de la transparencia
de un color (también conocido como el canal alfa). Esta opción está
desactivada por defecto. Si se llama a esta función con use_opacity
como TRUE se activa la transparencia. Si se utiliza use_opacity
como
FALSE se desactiva la transparencia.
void gtk_color_selection_set_color( GtkColorSelection *colorsel,
gdouble *color );
Puede poner el color actual explicitamente haciendo uso de esta función con
un puntero a un vector de colores (de tipo gdouble
). La longitud del
vector depende de si está activada la transparencia. La posición 0 contiene
la componente roja del color, la 1 contiene la verde, la 2 la azul y la
transparencia está en la posición 3 (solamente si está activada la
transparencia, ver gtk_color_selection_set_opacity()
). Todos los
valores se encuentran entre 0.0 y 1.0.
void gtk_color_selection_get_color( GtkColorSelection *colorsel,
gdouble *color );
Cuando necesite preguntar por el color actual, normalmente cuando haya
recibido una señal color_changed
, utilice esta función. color
es un puntero al vector de colores que se rellenará. Ver la descripción
de la función gtk_color_selection_set_color()
para conocer la
estructura de este vector.
Aquí tenemos un pequeño ejemplo que muestra el uso de
GtkColorSelectionDialog
. El programa muestra una ventana con una zona
de dibujo. Pulsando en ella se abre un cuadro de diálogo de selección
del color, y cambiando el color en el cuadro de diálogo se cambia el
color de fondo de la zona de dibujo.
/* principio del ejemplo colorsel colorsel.c */
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
GtkWidget *colorseldlg = NULL;
GtkWidget *drawingarea = NULL;
/* Manejador del cambio de color */
void color_changed_cb (GtkWidget *widget, GtkColorSelection *colorsel)
{
gdouble color[3];
GdkColor gdk_color;
GdkColormap *colormap;
/* Obtener el mapa de colores de la zona de dibujo */
colormap = gdk_window_get_colormap (drawingarea->window);
/* Obtener el color actual */
gtk_color_selection_get_color (colorsel,color);
/* Meterlo en un entero sin signo de 16 bits (0..65535) e insertarlo
en la estructura GdkColor */
gdk_color.red = (guint16)(color[0]*65535.0);
gdk_color.green = (guint16)(color[1]*65535.0);
gdk_color.blue = (guint16)(color[2]*65535.0);
/* Pedir memoria para el color */
gdk_color_alloc (colormap, &gdk_color);
/* Poner el color de fondo de la ventana */
gdk_window_set_background (drawingarea->window, &gdk_color);
/* Limpiar la ventana */
gdk_window_clear (drawingarea->window);
}
/* Manejador del evento Drawingarea */
gint area_event (GtkWidget *widget, GdkEvent *event, gpointer client_data)
{
gint handled = FALSE;
GtkWidget *colorsel;
/* Comprobar si hemos recibido un evento de pulsación de botón */
if (event->type == GDK_BUTTON_PRESS && colorseldlg == NULL)
{
/* Sí, ¡tenemos un evento y todavía no está el colorseldlg! */
handled = TRUE;
/* Crear el cuadro de diálogo de selección del color */
colorseldlg = gtk_color_selection_dialog_new("Select background color");
/* Obtener el widget GtkColorSelection */
colorsel = GTK_COLOR_SELECTION_DIALOG(colorseldlg)->colorsel;
/* Conectar con la señal ``color_changed'', darle al dato del
cliente el valor del widget colorsel */
gtk_signal_connect(GTK_OBJECT(colorsel), "color_changed",
(GtkSignalFunc)color_changed_cb, (gpointer)colorsel);
/* Mostrar el cuadro de diálogo */
gtk_widget_show(colorseldlg);
}
return handled;
}
/* Manipulador de los eventos cerrar y salir */
void destroy_window (GtkWidget *widget, gpointer client_data)
{
gtk_main_quit ();
}
/* Principal */
gint main (gint argc, gchar *argv[])
{
GtkWidget *window;
/* Inicializa el toolkit, y elimina las opciones relacionadas con
gtk incluidas en la línea de órdenes */
gtk_init (&argc,&argv);
/* Crea la ventana de más alto nivel, le da título y la política */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "Color selection test");
gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, TRUE);
/* Enlaza con los eventos ``delete'' y ``destroy'', para que podamos
salir */
gtk_signal_connect (GTK_OBJECT(window), "delete_event",
(GtkSignalFunc)destroy_window, (gpointer)window);
gtk_signal_connect (GTK_OBJECT(window), "destroy",
(GtkSignalFunc)destroy_window, (gpointer)window);
/* Crea la zona de dibujo, pone el tamaño y caza los eventos de los
botones */
drawingarea = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA(drawingarea), 200, 200);
gtk_widget_set_events (drawingarea, GDK_BUTTON_PRESS_MASK);
gtk_signal_connect (GTK_OBJECT(drawingarea), "event",
(GtkSignalFunc)area_event, (gpointer)drawingarea);
/* Add drawingarea to window, then show them both */
gtk_container_add (GTK_CONTAINER(window), drawingarea);
gtk_widget_show (drawingarea);
gtk_widget_show (window);
/* Entrar en el bucle principal de gtk (nunca sale de aquí) */
gtk_main ();
/* Para satisfacer a los compiladores pijos */
return 0;
}
/* final del ejemplo */
El widget de selección de ficheros nos proporciona una forma rápida y sencilla de mostrar un cuadro de diálogo para la selección de un fichero (¡sorpresa!). Ya viene con los botones Aceptar, Cancelar y ayuda. Una magnifica ayuda para acortar el tiempo de programación.
Para crear un nuevo cuadro de diálogo de selección de ficheros utilice:
GtkWidget *gtk_file_selection_new( gchar *title );
Para poner el nombre del fichero en el cuadro de diálogo, por ejemplo para poder utilizar un directorio o un fichero por defecto, utilice la función:
void gtk_file_selection_set_filename( GtkFileSelection *filesel,
gchar *filename );
Para obtener el texto que el usuario ha introducido, utilice la función:
gchar *gtk_file_selection_get_filename( GtkFileSelection *filesel );
También hay punteros a los widgets que contiene el cuadro de diálogo. Son los siguientes:
Lo más probable es que sólo utilice los punteros ok_button
,
cancel_button
, y help_button
para controlar cuando se pulsan.
Aquí incluímos un ejemplo robado de testgtk.c
, modificado
para que se puede ejecutar independientemente. Como puede ver, no es
muy complicado crear un widget para la selección de
ficheros. Aunque aparezca el botón de ayuda en la pantalla, no hace
nada y no tiene ninguna señal conectada.
/* principio del ejemplo filesel filesel.c */
#include <gtk/gtk.h>
/* Obtener el nombre del fichero e imprimirlo en la consola */
void file_ok_sel (GtkWidget *w, GtkFileSelection *fs)
{
g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)));
}
void destroy (GtkWidget *widget, gpointer data)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
GtkWidget *filew;
gtk_init (&argc, &argv);
/* Crear un nuevo widget de selección de ficheros */
filew = gtk_file_selection_new ("File selection");
gtk_signal_connect (GTK_OBJECT (filew), "destroy",
(GtkSignalFunc) destroy, &filew);
/* Conectar el ok_button con la función file_ok_sel */
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button),
"clicked", (GtkSignalFunc) file_ok_sel, filew );
/* Conectar el cancel_button con la destrucción del widget */
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button),
"clicked", (GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (filew));
/* Damos el nombre del fichero, como si fuese un cuadro de diálogo para
grabar ficheros y estuviesemos dando un nombre por defecto */
gtk_file_selection_set_filename (GTK_FILE_SELECTION(filew),
"penguin.png");
gtk_widget_show(filew);
gtk_main ();
return 0;
}
/* fin del ejemplo */