gtk/docs/es/gtkfaq-es-4.html

436 lines
15 KiB
HTML
Raw Normal View History

2000-04-23 09:19:58 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.6">
<TITLE>GTK+ FAQ: Desarrollo con GTK+</TITLE>
<LINK HREF="gtkfaq-es-5.html" REL=next>
<LINK HREF="gtkfaq-es-3.html" REL=previous>
<LINK HREF="gtkfaq-es.html#toc4" REL=contents>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<A HREF="gtkfaq-es-5.html">Next</A>
<A HREF="gtkfaq-es-3.html">Previous</A>
<A HREF="gtkfaq-es.html#toc4">Contents</A>
<HR NOSHADE>
<H2><A NAME="s4">4. Desarrollo con GTK+</A></H2>
<H2><A NAME="ss4.1">4.1 <20>C<EFBFBD>mo empiezo?</A>
</H2>
<P>Despu<EFBFBD>s de que ha instalado GTK+, hay un par de cosas que pueden
facilitarle el desarrollo de aplicaciones con <20>l. Est<73> el Tutor de
GTK+
<A HREF="http://www.gtk.org/tutorial/">&lt;http://www.gtk.org/tutorial/&gt;</A>, el cual est<73> en desarrollo
activo. Este tutorial le introducir<69> en la escritura de aplicaciones
utilizando C.
<P>El Tutor no contiene (todav<61>a) informaci<63>n sobre todos los
<EM>widgets</EM> que existen en GTK+. Para c<>digo de ejemplo sobre la
utilizaci<EFBFBD>n b<>sica de todos los <EM>widgets</EM> de GTK+, debe ver
el archivo gtk/testgtk.c (y archivos fuentes asociados) en la distribuci<63>n
GTK+. Ver estos ejemplos le dar<61> una buena base sobre lo que pueden hacer
los <EM>widgets</EM>.
<P>
<H2><A NAME="ss4.2">4.2 <20>Qu<51> <EM>widgets</EM> existen en GTK?</A>
</H2>
<P>El Tutor de GTK+ lista los siguientes <EM>widgets</EM>:
<PRE>
GtkObject
+GtkData
| +GtkAdjustment
| `GtkTooltips
`GtkWidget
+GtkContainer
| +GtkBin
| | +GtkAlignment
| | +GtkEventBox
| | +GtkFrame
| | | `GtkAspectFrame
| | +GtkHandleBox
| | +GtkItem
| | | +GtkListItem
| | | +GtkMenuItem
| | | | `GtkCheckMenuItem
| | | | `GtkRadioMenuItem
| | | `GtkTreeItem
| | +GtkViewport
| | `GtkWindow
| | +GtkColorSelectionDialog
| | +GtkDialog
| | | `GtkInputDialog
| | `GtkFileSelection
| +GtkBox
| | +GtkButtonBox
| | | +GtkHButtonBox
| | | `GtkVButtonBox
| | +GtkHBox
| | | +GtkCombo
| | | `GtkStatusbar
| | `GtkVBox
| | +GtkColorSelection
| | `GtkGammaCurve
| +GtkButton
| | +GtkOptionMenu
| | `GtkToggleButton
| | `GtkCheckButton
| | `GtkRadioButton
| +GtkCList
| `GtkCTree
| +GtkFixed
| +GtkList
| +GtkMenuShell
| | +GtkMenuBar
| | `GtkMenu
| +GtkNotebook
| +GtkPaned
| | +GtkHPaned
| | `GtkVPaned
| +GtkScrolledWindow
| +GtkTable
| +GtkToolbar
| `GtkTree
+GtkDrawingArea
| `GtkCurve
+GtkEditable
| +GtkEntry
| | `GtkSpinButton
| `GtkText
+GtkMisc
| +GtkArrow
| +GtkImage
| +GtkLabel
| | `GtkTipsQuery
| `GtkPixmap
+GtkPreview
+GtkProgressBar
+GtkRange
| +GtkScale
| | +GtkHScale
| | `GtkVScale
| `GtkScrollbar
| +GtkHScrollbar
| `GtkVScrollbar
+GtkRuler
| +GtkHRuler
| `GtkVRuler
`GtkSeparator
+GtkHSeparator
`GtkVSeparator
</PRE>
<P>
<H2><A NAME="ss4.3">4.3 <20>GTK+ es seguro ante m<>ltiples hilos?</A>
</H2>
<P>Aunque GTK+, como la mayor<6F>a de los juegos de herramientas para X,
no es seguro ante m<>ltiples hilos, esto no prohibe el desarrollo de
aplicaciones con m<>ltiples hilos con GTK+.
<P>Rob Browning (rlb@cs.utexas.edu) describe t<>cnicas de hilamiento
que pueden utilizarse con GTK+ (levemente modificado):
<P>B<EFBFBD>sicamente existen dos enfoques principales, el primero es sencillo,
y el segundo complicado. En el primero, simplemente hay que asegurarse
de que todas las interacciones de GTK+ (o X) se manejan por un, y solo un,
hilo. Cualquier otro hilo que desee dibujar algo tiene que notificarlo de
alguna manera al hilo "GTK+", y dejarlo que maneje el trabajo real.
<P>El segundo enfoque le permite llamar funciones de GTK+ (o X) desde cualquier
hilo, pero requiere sincronizaci<63>n cuidadosa. La idea b<>sica es crear
una exclusi<73>n mutua de protecci<63>n para X, de manera que nadie haga
llamadas X sin primero adquirir esta exclusi<73>n mutua.
<P>Observe que se trata de un peque<75>o esfuerzo, pero que le permitir<69> ser
potencialmente m<>s eficiente que un GTK+ completamente seguro ante
m<EFBFBD>ltiples hilos. Usted decide la granularidad del bloqueo de hilos.
Tambi<EFBFBD>n debe asegurarse que el hilo que llama a gtk_main mantiene la
cerradura cuando llama a gtk_main.
<P>Lo siguiente por lo que hay que preocuparse ya que se ten<65>a agarrada
la exclusi<73>n mutua global cuando se entr<74> a gtk_main, es que todos
los <EM>callbacks</EM> tambi<62>n la tendr<64>n. Esto significa que el
<EM>callback</EM> debe soltarla si va a llamar a cualquier otro c<>digo
que pueda readquirirla. De otra manera obtendr<64> un bloqueo mortal.
Tambi<EFBFBD>n hay que tener agarrada la exclusi<73>n mutua cuando finalmente
regresa del <EM>callback</EM>.
<P>Para permitir a otros hilos, adem<65>s del que llama a gtk_main, tener
acceso a la exclusi<73>n mutua, necesitamos registrar una funci<63>n de
trabajo con GTK que nos permita liberar la exclusi<73>n mutua
peri<EFBFBD>dicamente.
<P><EFBFBD>Por qu<71> GTK+ no puede ser seguro ante m<>ltiples hilos de
manera nativa?
<P>Complejidad, sobrecarga, y mano de obra. La proporci<63>n de programas
con hilos es todav<61>a razonablemente peque<75>a, y conseguir seguridad
ante hilos es muy dif<69>cil y le quita tiempo valioso al trabajo
principal de obtener una buena librer<65>a gr<67>fica terminada. Ser<65>a
muy agradable que GTK+ fuera seguro ante hilos "al sacarlo de la caja",
pero no es pr<70>ctico ahora mismo, y har<61>a a GTK+ sustancialmente menos
eficiente si no se maneja cuidadosamente.
<P>De cualquier manera, no es una prioridad esencial ya que existen remedios
relativamente buenos.
<P>
<H2><A NAME="ss4.4">4.4 <20>C<EFBFBD>mo puedo prevenir el redibujar y reacomodar tama<6D>os mientras cambio m<>ltiples <EM>widgets</EM>?</A>
</H2>
<P>
Utilize gtk_container_disable_resize y gtk_container_enable_resize alrededor
del c<>digo donde quiere cambiar varias cosas. Esto resultar<61> en mayor
velocidad ya que prevendr<64> tener que darle el tama<6D>o otra vez a la
jerarqu<EFBFBD>a de <EM>widget</EM> por completo.
<P>
<H2><A NAME="ss4.5">4.5 <20>C<EFBFBD>mo atrapo un evento de doble tecleo (en un <EM>widget</EM> de lista, por ejemplo)?</A>
</H2>
<P>Tim Janik escribi<62> a la lista gtk-list (ligeramente modificado):
<P>Defina un manejador de se<73>al:
<P>
<BLOCKQUOTE><CODE>
<PRE>
gint
signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)
{
if (GTK_IS_LIST_ITEM(widget) &amp;&amp;
(event->type==GDK_2BUTTON_PRESS ||
event->type==GDK_3BUTTON_PRESS) ) {
printf("I feel %s clicked on button %d\",
event->type==GDK_2BUTTON_PRESS ? "double" : "triple",
event->button);
}
return FALSE;
}
</PRE>
</CODE></BLOCKQUOTE>
<P>Y conecte el manejador a su objeto:
<P>
<BLOCKQUOTE><CODE>
<PRE>
{
/* lista, asuntos de inicializacion de articulos de lista */
gtk_signal_connect(GTK_OBJECT(list_item),
"button_press_event",
GTK_SIGNAL_FUNC(signal_handler_event),
NULL);
/* y/o */
gtk_signal_connect(GTK_OBJECT(list_item),
"button_release_event",
GTK_SIGNAL_FUNC(signal_handler_event),
NULL);
/* algo mas */
}
</PRE>
</CODE></BLOCKQUOTE>
<P>y, Owen Taylor escribi<62>:
<P>Observe que se recibir<69> la pulsaci<63>n del bot<6F>n de antemano, y
si est<73> haciendo esto para un bot<6F>n, tambi<62>n obtendr<64> una se<73>al
de "tecleado" para el bot<6F>n. (Esto es cierto para cualquier juego de
herramientas, ya que las computadoras no son buenas para leer la mente de
cada quien.)
<P>
<H2><A NAME="ss4.6">4.6 <20>C<EFBFBD>mo puedo averiguar cu<63>l es la selecci<63>n de un GtkList?</A>
</H2>
<P>
<P>Consiga la selecci<63>n con algo como esto:
<BLOCKQUOTE><CODE>
<PRE>
GList *sel;
sel = GTK_LIST(list)->selection;
</PRE>
</CODE></BLOCKQUOTE>
<P>As<EFBFBD> es como GList est<73> definido (sacado de glist.h):
<BLOCKQUOTE><CODE>
<PRE>
typedef struct _GList GList;
struct _GList
{
gpointer data;
GList *next;
GList *prev;
};
</PRE>
</CODE></BLOCKQUOTE>
<P>Una estructura GList es simplemente una estructura para listas doblemente
enlazadas. Existen varias funciones g_list_*() para modificar una lista
enlazada en glib.h. Sin embargo, la selecci<63>n GTK_LIST(MyGtkList)->selection
es mantenida por las funciones gtk_list_*() y no deben ser modificadas.
<P>El selection_mode del GtkList determina las facilidades de selecci<63>n de un
GtkList y por lo tanto los contenidos de GTK_LIST(AnyGtkList)->selection:
<P>
<PRE>
selection_mode GTK_LIST()->selection contents
------------------------------------------------------
GTK_SELECTION_SINGLE) la selecci<63>n es NULL
o contiene un puntero GList*
para un art<72>culo seleccionado individualmente
GTK_SELECTION_BROWSE) la selecci<63>n es NULL si la lista
no contiene widgets, de otra manera
contiene un puntero GList*
para una estructura GList.
GTK_SELECTION_MULTIPLE) la selecci<63>n es NULL si no se seleccionan
listitems para un apuntador GList*
para el primer art<72>culo seleccionado. Eso en
su lugar apunta a una estructura GList para el
segundo art<72>culo seleccionado y contin<69>a
GTK_SELECTION_EXTENDED) la selecci<63>n es NULL.
</PRE>
<P>El campo data de la estructura GList GTK_LIST(MyGtkList)->selection apunta
al primer GtkListItem que es seleccionado. De manera que si quiere determinar
cuales listitems est<73>n seleccionados debe hacer esto:
<P>Durante la in>
<HR><H3>Transfer interrupted!</H3>
>
{
gchar *list_items[]={
"Item0",
"Item1",
"foo",
"last Item",
};
guint nlist_items=sizeof(list_items)/sizeof(list_items[0]);
GtkWidget *list_item;
guint i;
list=gtk_list_new();
gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_MULTIPLE);
gtk_container_add(GTK_CONTAINER(AnyGtkContainer), list);
gtk_widget_show (list);
for (i = 0; i &lt; nlist_items; i++)
{
list_item=gtk_list_item_new_with_label(list_items[i]);
gtk_object_set_user_data(GTK_OBJECT(list_item), (gpointer)i);
gtk_container_add(GTK_CONTAINER(list), list_item);
gtk_widget_show(list_item);
}
}
</PRE>
</CODE></BLOCKQUOTE>
<P>Para tener conocimiento de la inicializaci<63>n:
<BLOCKQUOTE><CODE>
<PRE>
{
GList *items;
items=GTK_LIST(list)->selection;
printf("Selected Items: ");
while (items) {
if (GTK_IS_LIST_ITEM(items->data))
printf("%d ", (guint)
gtk_object_get_user_data(items->data));
items=items->next;
}
printf("\n");
}
</PRE>
</CODE></BLOCKQUOTE>
<H2><A NAME="ss4.7">4.7 <20>Acaso es posible desplegar un texto que se recorte para que quepa dentro del lugar que tenga asignado?</A>
</H2>
<P>El comportamiento de GTK+ (sin recorte) es una consecuencia de sus intentos
para conservar recursos de X. Los <EM>widgets</EM> etiqueta (entre otros) no
tienen su propia ventana X - simplemente dibujan su contenido en la ventana
de su padre. Aunque ser<65>a posible hacer que ocurran recortes al establecer
la m<>scara de recorte antes de dibujar el texto, esto podr<64>a causar una
penalizaci<EFBFBD>n substancial en el rendimiento.
<P>Es posible que, a largo plazo, la mejor soluci<63>n a tales problemas sea
simplemente cambiar gtk para que le de ventanas X a las etiquetas. Un remedio
a corto plazo es poner el <EM>widget</EM> de etiqueta dentro de otro
<EM>widget</EM> que s<> obtiene su propia ventana - un candidato posible puede ser el <EM>widget</EM> <EM>viewport</EM>.
<P>
<BLOCKQUOTE><CODE>
<PRE>
viewport = gtk_viewport (NULL, NULL);
gtk_widget_set_usize (viewport, 50, 25);
gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
gtk_widget_show(viewport);
label = gtk_label ("a really long label that won't fit");
gtk_container_add (GTK_CONTAINER(viewport), label);
gtk_widget_show (label);
</PRE>
</CODE></BLOCKQUOTE>
<P>Si estuviera haciendo esto para un mont<6E>n de <EM>widgets</EM>, querr<72>
copiar gtkviewport.c y arrancar la funcionalidad de sombra y ajuste (tal vez
quiera llamarlo GtkClipper).
<P>
<H2><A NAME="ss4.8">4.8 <20>Por qu<71> el contenido de un bot<6F>n no se mueve al presionar el bot<6F>n? Aqu<71> les env<6E>o un parche para que funcione de esa forma...</A>
</H2>
<P>De: Peter Mattis
<P>La raz<61>n por la cu<63>l los botones no mueven a su hijo abajo y a la derecha
cuando son presionados es porque no me parece que eso es lo que ocurre
visualmente. Mi visi<73>n de los botonos es que los miras de manera recta.
O sea, la interface de usuario tiende sobre un plano y t<> est<73>s sobre
<EFBFBD>l observ<72>ndolo de manera recta. Cuando un bot<6F>n es presionado se
mueve directamente lejos de t<>. Para ser absolutamente correcto supongo
que el hijo deber<65>a encojerse un poquito. Pero no veo por qu<71> el hijo
deber<EFBFBD>a moverse abajo y a la izquierda. Recurda, el hijo se supone que
est<EFBFBD> pegado a la superficie del bot<6F>n. No es bueno que luzca como si
el hijo se resbala sobre la superficie del bot<6F>n.
<P>En una nota m<>s pr<70>ctica, ya implant<6E> esto una vez y determin<69>
que no se ve<76>a bien y lo quit<69>.
<P>
<H2><A NAME="ss4.9">4.9 <20>C<EFBFBD>mo puedo definir una l<>nea de separaci<63>n como en un men<65>?</A>
</H2>
<P>Revise el
<A HREF="http://www.gtk.org/tutorial/">Tutor</A> para informaci<63>n sobre como crear men<65>s.
<P>Sin embargo, para crear una l<>nea de separaci<63>n en un men<65>,
simplemente inserte un art<72>culo de men<65> vac<61>o:
<P>
<BLOCKQUOTE><CODE>
<PRE>
menuitem = gtk_menu_item_new();
gtk_menu_append(GTK_MENU(menu), menuitem);
gtk_widget_show(menuitem);
</PRE>
</CODE></BLOCKQUOTE>
<P>
<H2><A NAME="ss4.10">4.10 <20>C<EFBFBD>mo puedo darle justificaci<63>n a la derecha a un men<65>, como Help, cuando utilizo MenuFactory?</A>
</H2>
<P>Utilice algo como lo que sigue:
<P>
<BLOCKQUOTE><CODE>
<PRE>
menu_path = gtk_menu_factory_find (factory, "&lt;MyApp>/Help");
gtk_menu_item_right_justify(menu_path->widget);
</PRE>
</CODE></BLOCKQUOTE>
<H2><A NAME="ss4.11">4.11 <20>C<EFBFBD>mo hago mi ventana modal? / <20>C<EFBFBD>mo hago una s<>la ventana activa?</A>
</H2>
<P>Despu<EFBFBD>s de haber creado su ventana, haga gtk_grab_add(my_window). Y
despu<EFBFBD>s de cerrar la ventana haga gtk_grab_remove(my_window).
<P>
<H2><A NAME="ss4.12">4.12 <20>Por qu<71> mi <EM>widget</EM> (ej. progressbar) no se actualiza?</A>
</H2>
<P>
<P>Probablemente usted est<73> haciendo todos los cambios dentro de una funci<63>n
sin devolver el control a gtk_main. La mayor<6F>a de las actualizaciones de
dibujo se colocan simplemente en una cola, la cual es procesada dentro de
gtk_main. Puede forzar que se procese la cola de dibujado utilizando algo como:
<P>
<BLOCKQUOTE><CODE>
<PRE>
while (gtk_events_pending())
gtk_main_iteration();
</PRE>
</CODE></BLOCKQUOTE>
<P>dentro de la funci<63>n que cambia el <EM>widget</EM>.
<P>Lo que el fragmento anterior hace es correr todos los eventos pendientes y
funciones ociosas de alta prioridad, luego regresa de inmediato (el dibujado
se realiza en una funci<63>n ociosa de alta prioridad).
<P>
<HR NOSHADE>
<A HREF="gtkfaq-es-5.html">Next</A>
<A HREF="gtkfaq-es-3.html">Previous</A>
<A HREF="gtkfaq-es.html#toc4">Contents</A>
</BODY>
</HTML>