1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
4 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.6">
5 <TITLE>GTK+ FAQ: Desarrollo con GTK+</TITLE>
6 <LINK HREF="gtkfaq-es-5.html" REL=next>
7 <LINK HREF="gtkfaq-es-3.html" REL=previous>
8 <LINK HREF="gtkfaq-es.html#toc4" REL=contents>
10 <BODY BGCOLOR="#FFFFFF">
11 <A HREF="gtkfaq-es-5.html">Next</A>
12 <A HREF="gtkfaq-es-3.html">Previous</A>
13 <A HREF="gtkfaq-es.html#toc4">Contents</A>
15 <H2><A NAME="s4">4. Desarrollo con GTK+</A></H2>
17 <H2><A NAME="ss4.1">4.1 ¿Cómo empiezo?</A>
20 <P>Después de que ha instalado GTK+, hay un par de cosas que pueden
21 facilitarle el desarrollo de aplicaciones con él. Está el Tutor de
23 <A HREF="http://www.gtk.org/tutorial/"><http://www.gtk.org/tutorial/></A>, el cual está en desarrollo
24 activo. Este tutorial le introducirá en la escritura de aplicaciones
26 <P>El Tutor no contiene (todavía) información sobre todos los
27 <EM>widgets</EM> que existen en GTK+. Para código de ejemplo sobre la
28 utilización básica de todos los <EM>widgets</EM> de GTK+, debe ver
29 el archivo gtk/testgtk.c (y archivos fuentes asociados) en la distribución
30 GTK+. Ver estos ejemplos le dará una buena base sobre lo que pueden hacer
33 <H2><A NAME="ss4.2">4.2 ¿Qué <EM>widgets</EM> existen en GTK?</A>
36 <P>El Tutor de GTK+ lista los siguientes <EM>widgets</EM>:
53 | | | | `GtkCheckMenuItem
54 | | | | `GtkRadioMenuItem
58 | | +GtkColorSelectionDialog
70 | | +GtkColorSelection
121 <H2><A NAME="ss4.3">4.3 ¿GTK+ es seguro ante múltiples hilos?</A>
124 <P>Aunque GTK+, como la mayoría de los juegos de herramientas para X,
125 no es seguro ante múltiples hilos, esto no prohibe el desarrollo de
126 aplicaciones con múltiples hilos con GTK+.
127 <P>Rob Browning (rlb@cs.utexas.edu) describe técnicas de hilamiento
128 que pueden utilizarse con GTK+ (levemente modificado):
129 <P>Básicamente existen dos enfoques principales, el primero es sencillo,
130 y el segundo complicado. En el primero, simplemente hay que asegurarse
131 de que todas las interacciones de GTK+ (o X) se manejan por un, y solo un,
132 hilo. Cualquier otro hilo que desee dibujar algo tiene que notificarlo de
133 alguna manera al hilo "GTK+", y dejarlo que maneje el trabajo real.
134 <P>El segundo enfoque le permite llamar funciones de GTK+ (o X) desde cualquier
135 hilo, pero requiere sincronización cuidadosa. La idea básica es crear
136 una exclusión mutua de protección para X, de manera que nadie haga
137 llamadas X sin primero adquirir esta exclusión mutua.
138 <P>Observe que se trata de un pequeño esfuerzo, pero que le permitirá ser
139 potencialmente más eficiente que un GTK+ completamente seguro ante
140 múltiples hilos. Usted decide la granularidad del bloqueo de hilos.
141 También debe asegurarse que el hilo que llama a gtk_main mantiene la
142 cerradura cuando llama a gtk_main.
143 <P>Lo siguiente por lo que hay que preocuparse ya que se tenía agarrada
144 la exclusión mutua global cuando se entró a gtk_main, es que todos
145 los <EM>callbacks</EM> también la tendrán. Esto significa que el
146 <EM>callback</EM> debe soltarla si va a llamar a cualquier otro código
147 que pueda readquirirla. De otra manera obtendrá un bloqueo mortal.
148 También hay que tener agarrada la exclusión mutua cuando finalmente
149 regresa del <EM>callback</EM>.
150 <P>Para permitir a otros hilos, además del que llama a gtk_main, tener
151 acceso a la exclusión mutua, necesitamos registrar una función de
152 trabajo con GTK que nos permita liberar la exclusión mutua
154 <P>¿Por qué GTK+ no puede ser seguro ante múltiples hilos de
156 <P>Complejidad, sobrecarga, y mano de obra. La proporción de programas
157 con hilos es todavía razonablemente pequeña, y conseguir seguridad
158 ante hilos es muy difícil y le quita tiempo valioso al trabajo
159 principal de obtener una buena librería gráfica terminada. Sería
160 muy agradable que GTK+ fuera seguro ante hilos "al sacarlo de la caja",
161 pero no es práctico ahora mismo, y haría a GTK+ sustancialmente menos
162 eficiente si no se maneja cuidadosamente.
163 <P>De cualquier manera, no es una prioridad esencial ya que existen remedios
164 relativamente buenos.
166 <H2><A NAME="ss4.4">4.4 ¿Cómo puedo prevenir el redibujar y reacomodar tamaños mientras cambio múltiples <EM>widgets</EM>?</A>
170 Utilize gtk_container_disable_resize y gtk_container_enable_resize alrededor
171 del código donde quiere cambiar varias cosas. Esto resultará en mayor
172 velocidad ya que prevendrá tener que darle el tamaño otra vez a la
173 jerarquía de <EM>widget</EM> por completo.
175 <H2><A NAME="ss4.5">4.5 ¿Cómo atrapo un evento de doble tecleo (en un <EM>widget</EM> de lista, por ejemplo)?</A>
178 <P>Tim Janik escribió a la lista gtk-list (ligeramente modificado):
179 <P>Defina un manejador de señal:
184 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
186 if (GTK_IS_LIST_ITEM(widget) &&
187 (event->type==GDK_2BUTTON_PRESS ||
188 event->type==GDK_3BUTTON_PRESS) ) {
189 printf("I feel %s clicked on button %d\",
190 event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
198 <P>Y conecte el manejador a su objeto:
203 /* lista, asuntos de inicializacion de articulos de lista */
205 gtk_signal_connect(GTK_OBJECT(list_item),
206 "button_press_event",
207 GTK_SIGNAL_FUNC(signal_handler_event),
212 gtk_signal_connect(GTK_OBJECT(list_item),
213 "button_release_event",
214 GTK_SIGNAL_FUNC(signal_handler_event),
221 <P>y, Owen Taylor escribió:
222 <P>Observe que se recibirá la pulsación del botón de antemano, y
223 si está haciendo esto para un botón, también obtendrá una señal
224 de "tecleado" para el botón. (Esto es cierto para cualquier juego de
225 herramientas, ya que las computadoras no son buenas para leer la mente de
228 <H2><A NAME="ss4.6">4.6 ¿Cómo puedo averiguar cuál es la selección de un GtkList?</A>
232 <P>Consiga la selección con algo como esto:
236 sel = GTK_LIST(list)->selection;
239 <P>Así es como GList está definido (sacado de glist.h):
242 typedef struct _GList GList;
252 <P>Una estructura GList es simplemente una estructura para listas doblemente
253 enlazadas. Existen varias funciones g_list_*() para modificar una lista
254 enlazada en glib.h. Sin embargo, la selección GTK_LIST(MyGtkList)->selection
255 es mantenida por las funciones gtk_list_*() y no deben ser modificadas.
256 <P>El selection_mode del GtkList determina las facilidades de selección de un
257 GtkList y por lo tanto los contenidos de GTK_LIST(AnyGtkList)->selection:
260 selection_mode GTK_LIST()->selection contents
261 ------------------------------------------------------
263 GTK_SELECTION_SINGLE) la selección es NULL
264 o contiene un puntero GList*
265 para un artículo seleccionado individualmente
267 GTK_SELECTION_BROWSE) la selección es NULL si la lista
268 no contiene widgets, de otra manera
269 contiene un puntero GList*
270 para una estructura GList.
271 GTK_SELECTION_MULTIPLE) la selección es NULL si no se seleccionan
272 listitems para un apuntador GList*
273 para el primer artículo seleccionado. Eso en
274 su lugar apunta a una estructura GList para el
275 segundo artículo seleccionado y continúa
277 GTK_SELECTION_EXTENDED) la selección es NULL.
279 <P>El campo data de la estructura GList GTK_LIST(MyGtkList)->selection apunta
280 al primer GtkListItem que es seleccionado. De manera que si quiere determinar
281 cuales listitems están seleccionados debe hacer esto:
283 <HR><H3>Transfer interrupted!</H3>
286 gchar *list_items[]={
292 guint nlist_items=sizeof(list_items)/sizeof(list_items[0]);
293 GtkWidget *list_item;
297 gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
298 gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
299 gtk_widget_show (list);
301 for (i = 0; i < nlist_items; i++)
303 list_item=gtk_list_item_new_with_label(list_items[i]);
304 gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
305 gtk_container_add(GTK_CONTAINER(list), list_item);
306 gtk_widget_show(list_item);
311 <P>Para tener conocimiento de la inicialización:
317 items=GTK_LIST(list)->selection;
319 printf("Selected Items: ");
321 if (GTK_IS_LIST_ITEM(items->data))
322 printf("%d ", (guint)
323 gtk_object_get_user_data(items->data));
330 <H2><A NAME="ss4.7">4.7 ¿Acaso es posible desplegar un texto que se recorte para que quepa dentro del lugar que tenga asignado?</A>
333 <P>El comportamiento de GTK+ (sin recorte) es una consecuencia de sus intentos
334 para conservar recursos de X. Los <EM>widgets</EM> etiqueta (entre otros) no
335 tienen su propia ventana X - simplemente dibujan su contenido en la ventana
336 de su padre. Aunque sería posible hacer que ocurran recortes al establecer
337 la máscara de recorte antes de dibujar el texto, esto podría causar una
338 penalización substancial en el rendimiento.
339 <P>Es posible que, a largo plazo, la mejor solución a tales problemas sea
340 simplemente cambiar gtk para que le de ventanas X a las etiquetas. Un remedio
341 a corto plazo es poner el <EM>widget</EM> de etiqueta dentro de otro
342 <EM>widget</EM> que sí obtiene su propia ventana - un candidato posible puede ser el <EM>widget</EM> <EM>viewport</EM>.
346 viewport = gtk_viewport (NULL, NULL);
347 gtk_widget_set_usize (viewport, 50, 25);
348 gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
349 gtk_widget_show(viewport);
351 label = gtk_label ("a really long label that won't fit");
352 gtk_container_add (GTK_CONTAINER(viewport), label);
353 gtk_widget_show (label);
356 <P>Si estuviera haciendo esto para un montón de <EM>widgets</EM>, querrá
357 copiar gtkviewport.c y arrancar la funcionalidad de sombra y ajuste (tal vez
358 quiera llamarlo GtkClipper).
360 <H2><A NAME="ss4.8">4.8 ¿Por qué el contenido de un botón no se mueve al presionar el botón? Aquí les envío un parche para que funcione de esa forma...</A>
364 <P>La razón por la cuál los botones no mueven a su hijo abajo y a la derecha
365 cuando son presionados es porque no me parece que eso es lo que ocurre
366 visualmente. Mi visión de los botonos es que los miras de manera recta.
367 O sea, la interface de usuario tiende sobre un plano y tú estás sobre
368 él observándolo de manera recta. Cuando un botón es presionado se
369 mueve directamente lejos de tí. Para ser absolutamente correcto supongo
370 que el hijo debería encojerse un poquito. Pero no veo por qué el hijo
371 debería moverse abajo y a la izquierda. Recurda, el hijo se supone que
372 está pegado a la superficie del botón. No es bueno que luzca como si
373 el hijo se resbala sobre la superficie del botón.
374 <P>En una nota más práctica, ya implanté esto una vez y determiné
375 que no se veía bien y lo quité.
377 <H2><A NAME="ss4.9">4.9 ¿Cómo puedo definir una línea de separación como en un menú?</A>
381 <A HREF="http://www.gtk.org/tutorial/">Tutor</A> para información sobre como crear menús.
382 <P>Sin embargo, para crear una línea de separación en un menú,
383 simplemente inserte un artículo de menú vacío:
387 menuitem = gtk_menu_item_new();
388 gtk_menu_append(GTK_MENU(menu), menuitem);
389 gtk_widget_show(menuitem);
393 <H2><A NAME="ss4.10">4.10 ¿Cómo puedo darle justificación a la derecha a un menú, como Help, cuando utilizo MenuFactory?</A>
396 <P>Utilice algo como lo que sigue:
400 menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help");
401 gtk_menu_item_right_justify(menu_path->widget);
404 <H2><A NAME="ss4.11">4.11 ¿Cómo hago mi ventana modal? / ¿Cómo hago una sóla ventana activa?</A>
407 <P>Después de haber creado su ventana, haga gtk_grab_add(my_window). Y
408 después de cerrar la ventana haga gtk_grab_remove(my_window).
410 <H2><A NAME="ss4.12">4.12 ¿Por qué mi <EM>widget</EM> (ej. progressbar) no se actualiza?</A>
414 <P>Probablemente usted está haciendo todos los cambios dentro de una función
415 sin devolver el control a gtk_main. La mayoría de las actualizaciones de
416 dibujo se colocan simplemente en una cola, la cual es procesada dentro de
417 gtk_main. Puede forzar que se procese la cola de dibujado utilizando algo como:
421 while (gtk_events_pending())
422 gtk_main_iteration();
425 <P>dentro de la función que cambia el <EM>widget</EM>.
426 <P>Lo que el fragmento anterior hace es correr todos los eventos pendientes y
427 funciones ociosas de alta prioridad, luego regresa de inmediato (el dibujado
428 se realiza en una función ociosa de alta prioridad).
431 <A HREF="gtkfaq-es-5.html">Next</A>
432 <A HREF="gtkfaq-es-3.html">Previous</A>
433 <A HREF="gtkfaq-es.html#toc4">Contents</A>