Rebell
29-10-2005, 14:17
Hallo.
Ich versuche seit Stunden, eine vernünftige Liste in eine GtkComboBox zu stecken, aber es vermag mir einfach nicht gelingen - trotz Beispielcode.
Was ich habe: Eine einfache ComboBox mit Text.
Was ich brauche: Ich benötige sozusagen mehrere Spalten, die ich dann nach belieben verstecken kann.
Wozu ich das brauche: Einfache Einträge in der ComboBox nützen mir nichts, weil ich deren Index nicht bestimmen kann, weil dieser fortlaufend bei 0 anfängt. Möchte ich aber Einträge aus einer Datenbank mit ID und Text in die ComboBox einbauen, benötige ich mehr als einfache Texte.
Schlau wie ich war, habe ich gelesen, dass es dafür GtkTreeModel gibt. Also hab ich gesucht und bin schnell fündig geworden. Das Beispiel funktioniert allerdings nur mit einem TreeView. Versuche ich das (gefüllte) TreeModel einer ComboBox zu übergeben, erscheint zwar der Tree, aber ohne Texte.
Weiß jemand wie das genau funktioniert?
Hier ist mein C-Code, den ich mir zusammengeschustert habe.
#include <gtk/gtk.h>
static GtkTreeModel *
create_and_fill_model (void)
{
GtkListStore *liststore;
GtkTreeIter toplevel, child;
liststore = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
/* Append an empty top-level row to the tree store.
* Iter will point to the new row */
gtk_list_store_append(liststore, &toplevel);
/* Append another empty top-level row to the tree store.
* Iter will point to the new row */
gtk_list_store_append(liststore, &toplevel);
gtk_list_store_set (liststore, &toplevel,
0, 1,
1, "Hans",
-1);
/* Append a child to the row we just added.
* Child will point to the new row */
gtk_list_store_append(liststore, &toplevel);
gtk_list_store_set (liststore, &toplevel,
0, 2,
1, "Adam",
-1);
return GTK_TREE_MODEL(liststore);
}
static GtkWidget *
create_view (void)
{
GtkTreeViewColumn *col;
GtkWidget *view;
GtkCellRenderer *renderer;
view = gtk_tree_view_new();
/* --- Column #1 --- */
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "ID");
/* pack tree view column into tree view */
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
/* REnderer für erste Spalte */
renderer = gtk_cell_renderer_text_new();
/* pack cell renderer into tree view column */
gtk_tree_view_column_pack_start(col, renderer, TRUE);
/* connect 'text' property of the cell renderer to
* model column that contains the first name */
gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
/* --- Column #2 --- */
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Name");
/* pack tree view column into tree view */
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
gtk_tree_selection_set_mode(gtk_tree_view_get_sele ction(GTK_TREE_VIEW(view)),
GTK_SELECTION_NONE);
return view;
}
int
main (int argc, char **argv)
{
GtkTreeModel *list;
GtkWidget *window, *combo, *view, *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
vbox = gtk_vbox_new (FALSE, 0);
//gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (window), vbox);
combo = gtk_combo_box_new();
list = create_and_fill_model();
view = create_view();
gtk_tree_view_set_model(GTK_TREE_VIEW(view), list);
g_object_unref(list);
gtk_combo_box_set_model(GTK_COMBO_BOX(combo), list);
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), view, FALSE, FALSE, 0);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
gcc combotree.c -o combotree `pkg-config gtk+-2.0 --cflags --libs`
Erklärung:
In der ComboBox, sowie im TreeView kommt ein Model aus 2 Spalten (ID, Name) zum Einsatz.
Wobei das TreeModel in Wirklichkeit ein ListStore ist.
Die ComboBox nimmt eigentlich NUR TreeModels an, wenn man es entsprechend castet auch List- bzw. TreeStores. In der GTK-Dokumentation steht, dass man ListStore und TreeStore in Verbindung von TreeView verwenden kann, aber mehr steht dazu nicht. Auch keine Erklärung wie man das in Elementen einbaut, die nur ein TreeModel unterstützen. Da ein TreeModel keine Daten halten kann, sondern nur deren Schnittstelle darstellt.
Im TreeView unter der ComboBox fehlt für die 2te Spalte der Renderer und deshalb wird nur die ID angezeigt. Da in der ComboBox die Einträge zwar enthalten sind aber nicht angezeigt werden, vermute ich dass dort auch ein Renderer rein muss - aber wie?
Ich versuche seit Stunden, eine vernünftige Liste in eine GtkComboBox zu stecken, aber es vermag mir einfach nicht gelingen - trotz Beispielcode.
Was ich habe: Eine einfache ComboBox mit Text.
Was ich brauche: Ich benötige sozusagen mehrere Spalten, die ich dann nach belieben verstecken kann.
Wozu ich das brauche: Einfache Einträge in der ComboBox nützen mir nichts, weil ich deren Index nicht bestimmen kann, weil dieser fortlaufend bei 0 anfängt. Möchte ich aber Einträge aus einer Datenbank mit ID und Text in die ComboBox einbauen, benötige ich mehr als einfache Texte.
Schlau wie ich war, habe ich gelesen, dass es dafür GtkTreeModel gibt. Also hab ich gesucht und bin schnell fündig geworden. Das Beispiel funktioniert allerdings nur mit einem TreeView. Versuche ich das (gefüllte) TreeModel einer ComboBox zu übergeben, erscheint zwar der Tree, aber ohne Texte.
Weiß jemand wie das genau funktioniert?
Hier ist mein C-Code, den ich mir zusammengeschustert habe.
#include <gtk/gtk.h>
static GtkTreeModel *
create_and_fill_model (void)
{
GtkListStore *liststore;
GtkTreeIter toplevel, child;
liststore = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
/* Append an empty top-level row to the tree store.
* Iter will point to the new row */
gtk_list_store_append(liststore, &toplevel);
/* Append another empty top-level row to the tree store.
* Iter will point to the new row */
gtk_list_store_append(liststore, &toplevel);
gtk_list_store_set (liststore, &toplevel,
0, 1,
1, "Hans",
-1);
/* Append a child to the row we just added.
* Child will point to the new row */
gtk_list_store_append(liststore, &toplevel);
gtk_list_store_set (liststore, &toplevel,
0, 2,
1, "Adam",
-1);
return GTK_TREE_MODEL(liststore);
}
static GtkWidget *
create_view (void)
{
GtkTreeViewColumn *col;
GtkWidget *view;
GtkCellRenderer *renderer;
view = gtk_tree_view_new();
/* --- Column #1 --- */
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "ID");
/* pack tree view column into tree view */
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
/* REnderer für erste Spalte */
renderer = gtk_cell_renderer_text_new();
/* pack cell renderer into tree view column */
gtk_tree_view_column_pack_start(col, renderer, TRUE);
/* connect 'text' property of the cell renderer to
* model column that contains the first name */
gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
/* --- Column #2 --- */
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Name");
/* pack tree view column into tree view */
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
gtk_tree_selection_set_mode(gtk_tree_view_get_sele ction(GTK_TREE_VIEW(view)),
GTK_SELECTION_NONE);
return view;
}
int
main (int argc, char **argv)
{
GtkTreeModel *list;
GtkWidget *window, *combo, *view, *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
vbox = gtk_vbox_new (FALSE, 0);
//gtk_widget_show (vbox);
gtk_container_add (GTK_CONTAINER (window), vbox);
combo = gtk_combo_box_new();
list = create_and_fill_model();
view = create_view();
gtk_tree_view_set_model(GTK_TREE_VIEW(view), list);
g_object_unref(list);
gtk_combo_box_set_model(GTK_COMBO_BOX(combo), list);
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), view, FALSE, FALSE, 0);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
gcc combotree.c -o combotree `pkg-config gtk+-2.0 --cflags --libs`
Erklärung:
In der ComboBox, sowie im TreeView kommt ein Model aus 2 Spalten (ID, Name) zum Einsatz.
Wobei das TreeModel in Wirklichkeit ein ListStore ist.
Die ComboBox nimmt eigentlich NUR TreeModels an, wenn man es entsprechend castet auch List- bzw. TreeStores. In der GTK-Dokumentation steht, dass man ListStore und TreeStore in Verbindung von TreeView verwenden kann, aber mehr steht dazu nicht. Auch keine Erklärung wie man das in Elementen einbaut, die nur ein TreeModel unterstützen. Da ein TreeModel keine Daten halten kann, sondern nur deren Schnittstelle darstellt.
Im TreeView unter der ComboBox fehlt für die 2te Spalte der Renderer und deshalb wird nur die ID angezeigt. Da in der ComboBox die Einträge zwar enthalten sind aber nicht angezeigt werden, vermute ich dass dort auch ein Renderer rein muss - aber wie?