2015-06-20 16 views
1

我是GTK的新手。我寫的最後一個GUI應用程序在Turbo C中使用了文本模式GUI,所以我有一點需要注意的地方。如何從樹形模型中獲取gtk3組合框的選擇

我正在使用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()從組合框中獲取索引。返回的索引對我沒有幫助。對於子樹項目,它只顯示相對於父項的位置。所以,我試圖拉出所選選項的文本。多一點搜索找到了我這條線從ComboBox拉文:

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

然而,調用這個給了我下面的錯誤,並返回(空)。

(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

這應該工作...編譯此代碼與評論中的命令。這是'完整'版本,使用模型等...如果您只是想從列表中選擇一個名稱,可以使用GtkComboBoxText,這更容易使用...

/* 
* 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; 
} 
+0

謝謝。那樣做了。訣竅是兩步走; 1)使用迭代器獲取組合框中的選定元素; 2)從組合框中拉出模型(或者如果它仍然懸掛着,我想你可以使用orignal moedel); 3)使用迭代器來索引組合框正在使用的原始樹結構作爲模型以獲取選定的值 –

相關問題