如何从树模型中选择gtk3组合框

时间:2015-06-20 03:38:18

标签: combobox treeview gtk

我是GTK的新手。我编写的最后一个GUI应用程序在Turbo C中使用了文本模式GUI,所以我有点追赶。

我正在使用GTK为一些最终将在嵌入式系统中的代码编写测试工具。我正在使用带有树模型的组合框来提供2级选择。我按照我想要的那样显示了组合框,虽然我没有很好地理解我刚刚从另一个堆栈溢出问题中复制和粘贴的cell_renderer部分。

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);

此代码用于显示组合框。现在我需要从组合框中选择。我尝试使用gtk_combo_box_get_active()从组合框中获取索引。返回的索引对我没有帮助。对于子树项,它仅显示相对于父项的位置。所以,我试图提取所选选项的文本。更多的搜索发现我这条线从组合框中拉出文本:

gchar * selection = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(MyCombobox))));

然而,调用它给了我以下错误,并返回(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

所以,更多谷歌搜索表明我需要用“条目”初始化组合框,因此更新了我对组合框的初始化:

combobox = gtk_combo_box_new_with_model_and_entry(model);

并取得部分成功!!现在我可以从组合框中拉出文本,它会在组合框下拉列表中显示两次选择文本。选择完成后,它会在框中显示单个。所以,如果我的模型文本是:

opt10  
    opt11  
opt20  
    opt21  

树显示每个项目两次(选择第一个opt11)

[opt10 opt10] >  opt10  opt10  
                [opt11  opt11]  
 opt20 opt20 >  

一旦我做出选择,(比如opt11),组合框就会正确显示所选文本,而我对gtk_entry_get_text(.....)的调用会像我期望的那样返回文本“opt11”。

所以,我已经走到了尽头。我想查询组合框以获得唯一标识树中项目的索引或文本字符串。我有文本字符串方法工作,但它使组合框选项显示两次。

帮助?

谢谢,

1 个答案:

答案 0 :(得分:1)

这应该可行...使用注释中的命令编译此代码。这是“完整”版本,使用模型等...如果你只想从列表中选择一个名字,你可以使用GtkComboBoxText,它更容易使用......

/*
 * main.c
 * Copyright (C) 2015 John Coppens <john@jcoppens.com>
 * 
 * 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;
}