]> Pileus Git - ~andy/gtk/blob - docs/es/gtkfaq-es-4.html
443a9403661ea4d2e97801ff1ea0d4957007d128
[~andy/gtk] / docs / es / gtkfaq-es-4.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2 <HTML>
3 <HEAD>
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>
9 </HEAD>
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>
14 <HR NOSHADE>
15 <H2><A NAME="s4">4. Desarrollo con GTK+</A></H2>
16
17 <H2><A NAME="ss4.1">4.1 ¿Cómo empiezo?</A>
18 </H2>
19
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
22 GTK+ 
23 <A HREF="http://www.gtk.org/tutorial/">&lt;http://www.gtk.org/tutorial/&gt;</A>, el cual está en desarrollo
24 activo. Este tutorial le introducirá en la escritura de aplicaciones 
25 utilizando C.
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
31 los <EM>widgets</EM>.
32 <P>
33 <H2><A NAME="ss4.2">4.2 ¿Qué <EM>widgets</EM> existen en GTK?</A>
34 </H2>
35
36 <P>El Tutor de GTK+ lista los siguientes <EM>widgets</EM>:
37 <PRE>
38   GtkObject
39    +GtkData
40    | +GtkAdjustment
41    | `GtkTooltips
42    `GtkWidget
43      +GtkContainer
44      | +GtkBin
45      | | +GtkAlignment
46      | | +GtkEventBox
47      | | +GtkFrame
48      | | | `GtkAspectFrame
49      | | +GtkHandleBox
50      | | +GtkItem
51      | | | +GtkListItem
52      | | | +GtkMenuItem
53      | | | | `GtkCheckMenuItem
54      | | | |   `GtkRadioMenuItem
55      | | | `GtkTreeItem
56      | | +GtkViewport
57      | | `GtkWindow
58      | |   +GtkColorSelectionDialog
59      | |   +GtkDialog
60      | |   | `GtkInputDialog
61      | |   `GtkFileSelection
62      | +GtkBox
63      | | +GtkButtonBox
64      | | | +GtkHButtonBox
65      | | | `GtkVButtonBox
66      | | +GtkHBox
67      | | | +GtkCombo
68      | | | `GtkStatusbar
69      | | `GtkVBox
70      | |   +GtkColorSelection
71      | |   `GtkGammaCurve
72      | +GtkButton
73      | | +GtkOptionMenu
74      | | `GtkToggleButton
75      | |   `GtkCheckButton
76      | |     `GtkRadioButton
77      | +GtkCList
78      |   `GtkCTree
79      | +GtkFixed
80      | +GtkList
81      | +GtkMenuShell
82      | | +GtkMenuBar
83      | | `GtkMenu
84      | +GtkNotebook
85      | +GtkPaned
86      | | +GtkHPaned
87      | | `GtkVPaned
88      | +GtkScrolledWindow
89      | +GtkTable
90      | +GtkToolbar
91      | `GtkTree
92      +GtkDrawingArea
93      | `GtkCurve
94      +GtkEditable
95      | +GtkEntry
96      | | `GtkSpinButton
97      | `GtkText
98      +GtkMisc
99      | +GtkArrow
100      | +GtkImage
101      | +GtkLabel
102      | | `GtkTipsQuery
103      | `GtkPixmap
104      +GtkPreview
105      +GtkProgressBar
106      +GtkRange
107      | +GtkScale
108      | | +GtkHScale
109      | | `GtkVScale
110      | `GtkScrollbar
111      |   +GtkHScrollbar
112      |   `GtkVScrollbar
113      +GtkRuler
114      | +GtkHRuler
115      | `GtkVRuler
116      `GtkSeparator
117        +GtkHSeparator
118        `GtkVSeparator
119 </PRE>
120 <P>
121 <H2><A NAME="ss4.3">4.3 ¿GTK+ es seguro ante múltiples hilos?</A>
122 </H2>
123
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 
153 periódicamente.
154 <P>¿Por qué GTK+ no puede ser seguro ante múltiples hilos de
155 manera nativa?
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.
165 <P>
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>
167 </H2>
168
169 <P> 
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.
174 <P>
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>
176 </H2>
177
178 <P>Tim Janik escribió a la lista gtk-list (ligeramente modificado):
179 <P>Defina un manejador de señal:
180 <P>
181 <BLOCKQUOTE><CODE>
182 <PRE>
183 gint
184 signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
185 {
186   if (GTK_IS_LIST_ITEM(widget) &amp;&amp;
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",
191            event->button);
192   }
193
194   return FALSE;
195 }
196 </PRE>
197 </CODE></BLOCKQUOTE>
198 <P>Y conecte el manejador a su objeto:
199 <P>
200 <BLOCKQUOTE><CODE>
201 <PRE>
202 {
203   /* lista, asuntos de inicializacion de articulos de lista */     
204
205   gtk_signal_connect(GTK_OBJECT(list_item),
206                      "button_press_event",
207                      GTK_SIGNAL_FUNC(signal_handler_event),
208                      NULL);
209
210   /* y/o */
211
212   gtk_signal_connect(GTK_OBJECT(list_item),
213                      "button_release_event",
214                      GTK_SIGNAL_FUNC(signal_handler_event),
215                      NULL);
216
217   /* algo mas */
218 }
219 </PRE>
220 </CODE></BLOCKQUOTE>
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
226 cada quien.)
227 <P>
228 <H2><A NAME="ss4.6">4.6 ¿Cómo puedo averiguar cuál es la selección de un GtkList?</A>
229 </H2>
230
231 <P>
232 <P>Consiga la selección con algo como esto:
233 <BLOCKQUOTE><CODE>
234 <PRE>
235 GList *sel;
236 sel = GTK_LIST(list)->selection;
237 </PRE>
238 </CODE></BLOCKQUOTE>
239 <P>Así es como GList está definido (sacado de glist.h):
240 <BLOCKQUOTE><CODE>
241 <PRE>
242 typedef struct _GList GList;
243
244 struct _GList
245 {
246   gpointer data;
247   GList *next;
248   GList *prev;
249 };
250 </PRE>
251 </CODE></BLOCKQUOTE>
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:
258 <P>
259 <PRE>
260 selection_mode          GTK_LIST()->selection contents
261 ------------------------------------------------------
262
263 GTK_SELECTION_SINGLE)   la selección es NULL
264                         o contiene un puntero GList*
265                         para un artículo seleccionado individualmente
266
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
276
277 GTK_SELECTION_EXTENDED) la selección es NULL.
278 </PRE>
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:
282 <P>Durante la in>
283 <HR><H3>Transfer interrupted!</H3>
284 >
285 {
286         gchar           *list_items[]={
287                                 "Item0",
288                                 "Item1",
289                                 "foo",
290                                 "last Item",
291                         };
292         guint           nlist_items=sizeof(list_items)/sizeof(list_items[0]);
293         GtkWidget       *list_item;
294         guint           i;
295
296         list=gtk_list_new();
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);
300
301         for (i = 0; i &lt; nlist_items; i++)
302         {
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);
307         }
308 }
309 </PRE>
310 </CODE></BLOCKQUOTE>
311 <P>Para tener conocimiento de la inicialización:
312 <BLOCKQUOTE><CODE>
313 <PRE>
314 {
315         GList   *items;
316
317         items=GTK_LIST(list)->selection;
318
319         printf("Selected Items: ");
320         while (items) {
321                 if (GTK_IS_LIST_ITEM(items->data))
322                         printf("%d ", (guint) 
323                 gtk_object_get_user_data(items->data));
324                 items=items->next;
325         }
326         printf("\n");
327 }
328 </PRE>
329 </CODE></BLOCKQUOTE>
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>
331 </H2>
332
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>.
343 <P>
344 <BLOCKQUOTE><CODE>
345 <PRE>
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);
350
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);
354 </PRE>
355 </CODE></BLOCKQUOTE>
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).
359 <P>
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>
361 </H2>
362
363 <P>De: Peter Mattis
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é.
376 <P>
377 <H2><A NAME="ss4.9">4.9 ¿Cómo puedo definir una línea de separación como en un menú?</A>
378 </H2>
379
380 <P>Revise el 
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:
384 <P>
385 <BLOCKQUOTE><CODE>
386 <PRE>
387 menuitem = gtk_menu_item_new();
388 gtk_menu_append(GTK_MENU(menu), menuitem);
389 gtk_widget_show(menuitem);
390 </PRE>
391 </CODE></BLOCKQUOTE>
392 <P>
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>
394 </H2>
395
396 <P>Utilice algo como lo que sigue:
397 <P>
398 <BLOCKQUOTE><CODE>
399 <PRE>
400 menu_path = gtk_menu_factory_find (factory,  "&lt;MyApp>/Help");
401 gtk_menu_item_right_justify(menu_path->widget);
402 </PRE>
403 </CODE></BLOCKQUOTE>
404 <H2><A NAME="ss4.11">4.11 ¿Cómo hago mi ventana modal? / ¿Cómo hago una sóla ventana activa?</A>
405 </H2>
406
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).
409 <P>
410 <H2><A NAME="ss4.12">4.12 ¿Por qué mi <EM>widget</EM> (ej. progressbar) no se actualiza?</A>
411 </H2>
412
413 <P>
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:
418 <P>
419 <BLOCKQUOTE><CODE>
420 <PRE>
421 while (gtk_events_pending())
422         gtk_main_iteration();
423 </PRE>
424 </CODE></BLOCKQUOTE>
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).
429 <P>
430 <HR NOSHADE>
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>
434 </BODY>
435 </HTML>