Reputation: 209
I'm new to GTK. The last GUI application I wrote used the text mode GUI in Turbo C, so I have a little catching up to do.
I'm using GTK to write a test harness for some code that will eventually be in an embedded system. I'm using a combobox with a tree model to provide a 2-level selection. I got the combobox to display as I wanted, although I don't have a good understaning of the cell_renderer parts that I just copied and pasted from another stack overflow question.
GtkTreeStore* model = gtk_tree_store_new(1,G_TYPE_STRING)
(Initilise model to hold desired strings using
gtk_tree_store_append and gtk_tree_store_set)
GtkWidget* combobox = gtk_combo_box_new_with_model(model);
gtk_combo_box_set_entry_text_column(combobox, 0);
GtkCellRenderer *column = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox),column,TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), column,"text", 0,NULL);
This code worked to display the combobox. Now I needed to get the selection from the combobox. I tried getting an index from the combobox using gtk_combo_box_get_active (). The index returned didn't help me. For sub-tree items, It only showed the position relative to the parent. So, I tried to pull out the text of the selected option. A bit more searching found me this line to pull the text from the combobox:
gchar * selection = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(MyCombobox))));
however, calling this gave me the following error, and returned (null).
(test.exe:3040): GLib-GObject-WARNING **: invalid cast from `GtkCellView' to `GtkEntry'
(test.exe:3040): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed
So, a bit more googling indicated that I need to initialise the combobox with an "entry", so updated my initialisation of the combobox to:
combobox = gtk_combo_box_new_with_model_and_entry(model);
And partial success!!. Now I can pull the text from the combobox, but it displays the selection text twice, on the combobox drop-down. Once the selection is made, it displays single in the box itself. so, if my model text is:
opt10
opt11
opt20
opt21
The tree displays each item twice (selecting first opt11)
[opt10 opt10] > opt10 opt10
[opt11 opt11]
opt20 opt20 >
Once I make my selection, (say opt11) the combobox shows the selected text correctly, and my call to gtk_entry_get_text(.....) returns the text "opt11" like I expect.
So, I'm at a dead-end. I want to query the combobox to get either an index that uniquely identifies the item in the tree, or a text string. I have the text string method working, but it makes the combobox options display twice.
Help?
Thanks,
Upvotes: 1
Views: 1883
Reputation: 5440
This should work... Compile this code with the command in the comments. This is the 'full' version, using a model and such... If you just want to select a name from a list, you can use GtkComboBoxText, which is easier to use...
/*
* main.c
* Copyright (C) 2015 John Coppens <[email protected]>
*
* standalone_filechooser is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* standalone_filechooser is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*
* gcc -o main `pkg-config --libs --cflags gtk+-3.0` main.c
*/
#include <stdio.h>
#include <gtk/gtk.h>
int
on_destroy(GtkWidget *win, gpointer data)
{
gtk_main_quit();
return FALSE;
}
void
sel_changed(GtkComboBox *cbbox, gpointer data)
{
GtkListStore *store;
GtkTreeIter iter;
int item_nr, ok;
char *item;
ok = gtk_combo_box_get_active_iter(cbbox, &iter);
printf("%i\n", ok);
store = GTK_LIST_STORE(gtk_combo_box_get_model(cbbox));
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
0, &item_nr,
1, &item,
-1);
printf("Item: %s, nr: %d\n", item, item_nr);
g_free(item);
}
int main(int argc, char *argv[])
{
GtkWidget *win, *cbbox;
GtkCellRenderer *col;
GtkListStore *store;
GtkTreeIter iter;
int i;
char *items[] = {"Thingie 1", "Thingie 2", "Thingie 3"};
gtk_init(&argc, &argv);
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
store = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
for (i = 0; i < sizeof(items)/sizeof(char *); i++) {
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, i,
1, items[i],
-1);
}
cbbox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(store);
col = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cbbox), col, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cbbox), col,
"text", 1,
NULL);
gtk_combo_box_set_id_column(GTK_COMBO_BOX(cbbox), 1);
g_signal_connect(G_OBJECT(cbbox), "changed", G_CALLBACK(sel_changed), NULL);
gtk_container_add(GTK_CONTAINER(win), cbbox);
gtk_widget_show_all(win);
gtk_main();
return 0;
}
Upvotes: 1