Obtén la selección con algo así:
GList *sel; sel = GTK_LIST(list)->selection; |
Así es como GList está definido (citando glist.h):
typedef struct _GList GList; struct _GList { gpointer data; GList *next; GList *prev; }; |
Una estructura GList es simplemente una estructura para listas doblemente enlazadas. En glib.h existen varias funciones g_list_*() para modificar una lista enlazada. Sin embargo, la selección GTK_LIST(MyGtkList)->selection es mantenida por las funciones gtk_list_*() y no debe ser modificada.
El selection_mode del GtkList determina las facilidades de selección de un GtkList y por lo tanto los de GTK_LIST(AnyGtkList)->selection:
selection_mode | GTK_LIST()->selection contents |
---|---|
GTK_SELECTION_SINGLE | selection es NULL o contiene un puntero a GList* para un artículo singular seleccionado. |
GTK_SELECTION_BROWSE | selection es NULL si la lista no contiene widgets, de otra manera contiene un puntero a GList* para una estructura GList. |
GTK_SELECTION_MULTIPLE | selection es NULL si no hay artículos de la lista seleccionados o un puntero a GList* para el primer artículo seleccionado, que en su lugar apunta a una estructura GList para el segundo artículo seleccionado y continúa. |
GTK_SELECTION_EXTENDED | selection es NULL. |
El campo de datos GTK_LIST(MyGtkList)->selection de la estructura GList apunta al primer GtkListItem que está seleccionado. Así que si quieres determinar que artículos de la lista están seleccionados deberías hacer algo como esto:
{ 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 < 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); } } |
Para conocer sobre la selección:
{ 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"); } |
Esto ocurre cuando una GtkCList se empaqueta en un GtkScrolledWindow usando la función gtk_scroll_window_add_with_viewport(). El método preferido para agregar un CList a una ventana que se enrolla es usando la función gtk_container_add, como en:
GtkWidget *scrolled, *clist; char *titles[] = { "Title1" , "Title2" }; scrolled = gtk_scrolled_window_new(NULL, NULL); clist = gtk_clist_new_with_titles(2, titles); gtk_container_add(GTK_CONTAINER(scrolled), clist); |
Un GtkCombo tiene una entrada asociada a la cual se puede acceder usando las expresiones siguientes:
GTK_COMBO(combo_widget)->entry |
Si no quieres que el usuario pueda modificar el contenido de esta entrada, puedes usar la función gtk_entry_set_editable():
void gtk_entry_set_editable(GtkEntry *entry, gboolean editable); |
Asigna FALSE al parámetro editable para deshabilitar el tecleado en la entrada.
La entrada asociado con tu GtkCombo envía una señal "changed" cuando:
se tecleada algún texto
se cambia la selección del combo box
Para atrapar cualquier cambio en el combo box, simplemente conecta tu manejador de señal con
gtk_signal_connect(GTK_COMBO(cb)->entry, "changed", GTK_SIGNAL_FUNC(my_cb_change_handler), NULL); |
Revisa el Tutorial para obtener información sobre cómo crear menús. Sin embargo, para crear una línea de separación en un menú, simplemente inserta un artículo vacío en el menú:
menuitem = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), menuitem); gtk_widget_show(menuitem); |
Dependiendo de si usas el MenuFactory o no, hay dos maneras de proceder. Con el MenuFactory, usa algo como lo que sigue:
menu_path = gtk_menu_factory_find (factory, "<MyApp>/Help"); gtk_menu_item_right_justify(menu_path->widget); |
Si no usas el MenuFactory, usa simplemente:
gtk_menu_item_right_justify(my_menu_item); |
Damon Chaplin, la fuerza técnica detrás del proyecto Glade, proporcionó el siguiente ejemplo de código (este código es una salida de Glade). Crea un artículo de menú pequeño File con un solo hijo (New). La F en File y la N en New están subrayadas, y se crean los aceleradores relevantes.
menubar1 = gtk_menu_bar_new (); gtk_object_set_data (GTK_OBJECT (window1), "menubar1", menubar1); gtk_widget_show (menubar1); gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0); file1 = gtk_menu_item_new_with_label (""); tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (file1)->child), _("_File")); gtk_widget_add_accelerator (file1, "activate_item", accel_group, tmp_key, GDK_MOD1_MASK, 0); gtk_object_set_data (GTK_OBJECT (window1), "file1", file1); gtk_widget_show (file1); gtk_container_add (GTK_CONTAINER (menubar1), file1); file1_menu = gtk_menu_new (); file1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (file1_menu)); gtk_object_set_data (GTK_OBJECT (window1), "file1_menu", file1_menu); gtk_menu_item_set_submenu (GTK_MENU_ITEM (file1), file1_menu); new1 = gtk_menu_item_new_with_label (""); tmp_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (new1)->child), _("_New")); gtk_widget_add_accelerator (new1, "activate_item", file1_menu_accels, tmp_key, 0, 0); gtk_object_set_data (GTK_OBJECT (window1), "new1", new1); gtk_widget_show (new1); gtk_container_add (GTK_CONTAINER (file1_menu), new1); |
Usualmente puedes obtener la etiqueta de un GtkMenuItem específico con:
if (GTK_BIN (menu_item)->child) { GtkWidget *child = GTK_BIN (menu_item)->child; /* hacer cosas con el hijo */ if (GTK_IS_LABEL (child)) { gchar *text; gtk_label_get (GTK_LABEL (child), &text); g_print ("menu item text: %s\n", text); } } |
Para obtener el artículo activo de un GtkOptionMenu puedes hacer:
if (GTK_OPTION_MENU (option_menu)->menu_item) { GtkWidget *menu_item = GTK_OPTION_MENU (option_menu)->menu_item; } |
Pero hay una trampa. Para este caso específico, no puedes obtener el widget etiqueta de menu_item con el código anterior, porque el menú de opción cambia el padre del hijo de menu_item temporalmente para desplegar los contenidos actualmente activos. Así que para rescatar el hijo de menu_item actualmente activo de un menú de opción, debes hacer esto:
if (GTK_BIN (option_menu)->child) { GtkWidget *child = GTK_BIN (option_menu)->child; /* hacer cosas con el hijo */ } |
¿Estás seguro de querer justificar las etiquetas? La clase label contiene la función gtk_label_set_justify() que se usa para controlar la justificación de una etiqueta con múltiples líneas.
Lo que probablemente quieres hacer es asignar la alineación de la etiqueta, ej alinearlo a la derecha, centrarlo o alinearlo a la izquierda. Si quieres hacer esto, debes usar:
void gtk_misc_set_alignment (GtkMisc *misc, gfloat xalign, gfloat yalign); |
dónde los valores xalign y yalign son de punto flotante con rango [0.00;1.00].
GtkWidget *label; /* horizontal : alinear a la izquierda, vertical : arriba */ gtk_misc_set_alignment(GTK_MISK(label), 0.0f, 0.0f); /* horizontal : centreado, vertical : centreado */ gtk_misc_set_alignment(GTK_MISK(label), 0.5f, 0.5f); /* horizontal : alineado a la derecha, vertical : abajo */ gtk_misc_set_alignment(GTK_MISK(label), 1.0f, 1.0f); |
El widget GtkLabel es uno de los pocos widgets GTK+ que no crean su propia ventana para dibujarse a sí mismos. En cambio, se dibujan en la ventana de su padre.
Esto significa que para asignar el color de fondo de un widget GtkLabel, necesitas cambiar el color de fondo de su padre, ej. el objeto en el que lo empaquetaste.
El camino del nombre de widget construido para una etiqueta se compone con los nombres de widgets de su jerarquía de objetos, ej.
window (name: humphrey)
hbox
label (name: mylabel)
El camino del widget que tu patrón necesita igualar debe ser: humphrey.GtkHBox.mylabel
El archivo de recursos puede lucir algo como esto:
style "title" { fg[NORMAL] = {1.0, 0.0, 0.0} font = "-adobe-helvetica-bold-r-normal--*-140-*-*-*-*-*-*" } widget "*mylabel" style "title" |
En tu programa, también tendrías que dar un nombre al widget etiqueta, lo que puede hacerse usando:
label = gtk_label_new("Some Label Text"); gtk_widget_set_name(label, "mylabel"); gtk_widget_show(label); |
La ventana del tooltip se llama "gtk-tooltips", GtkTooltips no es un GtkWidget en sí mismo (aunque es un GtkObject) y como tal no intenta empatar con algún estilo de widget.
Por lo tanto, tu archivo de recursos debe lucir algo como esto:
style "postie" { bg[NORMAL] = {1.0, 1.0, 0.0} } widget "gtk-tooltips*" style "postie" |
Hay un problema conocido en el widget GtkEntry. En la función gtk_entry_insert_text(), las siguientes líneas limitan el número de caracteres en la entrada a 2047.
/* The algorithms here will work as long as, the text size (a * multiple of 2), fits into a guint16 but we specify a shorter * maximum length so that if the user pastes a very long text, there * is not a long hang from the slow X_LOCALE functions. */ if (entry->text_max_length == 0) max_length = 2047; else max_length = MIN (2047, entry->text_max_length); |
El widget Entry emite la señal 'activate' cuando se pulsa la tecla 'return'. Simplemente conecte con la señal activa de GtkEntry y haga lo que desee. Un código típico seria el siguiente:
entry = gtk_entry_new(); gtk_signal_connect (GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(entry_callback), NULL); |
Si quieres validar el texto que introduce un usuario a un widget GtkEntry, puede pegarse a la señal "insert_text" de la entrada, y modificar el texto dentro de la función callback. El ejemplo siguiente fuerza todos los caracteres a ser mayúsculas, y limita el rango de caracteres en A-Z. Nota que la entrada está moldeada a un objeto de tipo GtkEditable, del cual se deriva GtkEntry.
#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); } |
La respuesta corta es que no puedes. La versión actual del widget GtkText no soporta enrrollamiento horizontal. Hay intención de reescribir completamente el widget GtkText, momento en el cual esta limitación será solventada.
Hay un par de maneras de hacerlo. Como GTK+ permite que la apariencia de las aplicaciones cambie en tiempo de ejecución utilizando recursos, puedes usar algo como lo siguiente en el archivo apropiado:
style "text" { font = "-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*" } |
Otra manera de hacerlo es cargando un font dentro del programa, y entonces usar esto en las funciones para agregar texto a widget de texto. Puedes cargar un font usando, por ejemplo:
GdkFont *font; font = gdk_font_load("-adobe-helvetica-medium-r-normal--*-140-*-*-*-*-*-*"); |
Ten en cuenta que la respuesta es válida para cualquier objeto que hereda de la clase GtkEditable.
¿Estás seguro que deseas mover la posición del cursor? La mayor parte del tiempo, mientras la posición del cursor es buena, el punto de inserción no se empareja con la posición del cursor. Si esto se aplica a lo que quieres en realidad, entonces deberías usar la función gtk_text_set_point(). Si quieres colocar el punto de inserción en la posición actual del cursor, usa lo siguiente:
gtk_text_set_point(GTK_TEXT(text), gtk_editable_get_position(GTK_EDITABLE(text))); |
Si quieres que el punto de inserción siga al cursor todo el tiempo, probablemente deberías atrapar el evento de presión de botón, y entonces mover el punto de inserción. Se cuidadoso: deberás atraparlo después de que el widget ha cambiado la posición del cursor. Thomas Mailund Jensen propuso el siguiente código:
static void insert_bar (GtkWidget *text) { /* brincar a la marca del cursor */ gtk_text_set_point (GTK_TEXT (text), gtk_editable_get_position (GTK_EDITABLE (text))); gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL, "bar", strlen ("bar")); } int main (int argc, char *argv[]) { GtkWidget *window, *text; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); text = gtk_text_new (NULL, NULL); gtk_text_set_editable (GTK_TEXT (text), TRUE); gtk_container_add (GTK_CONTAINER (window), text); /* conectar después de todo lo demás */ gtk_signal_connect_after (GTK_OBJECT(text), "button_press_event", GTK_SIGNAL_FUNC (insert_bar), NULL); gtk_widget_show_all(window); gtk_main(); return 0; } |
Ahora, si en realidad quieres cambiar la posición del cursor, debes usar la función gtk_editable_set_position().