从Gtk TreeStore中删除行时出错

时间:2015-05-05 00:27:37

标签: c gtk gtk3

我有一个从列表库中删除单独选择的行的功能,但每次调用它时,都会收到一条错误:

Gtk-CRITICAL **: gtk_list_store_remove: assertion `iter_is_valid (iter, list_store)' failed

这是功能:

void delete_row()
{

    selector = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    gtk_tree_selection_get_selected(selector, &model, &iter);
    gtk_list_store_remove(GTK_LIST_STORE(store), &iter);

}

选择模式设置为单一。我在不同的函数中使用相同的模型和迭代器,没有任何问题。

我是否以正确的方式解决这个问题?我的代码基于以下教程:

http://en.wikibooks.org/wiki/GTK%2B_By_Example/Tree_View/Events

**编辑**

注意:我也尝试使用gtk_list_store_remove(GTK_LIST_STORE(model), &iter);,这会产生同样的错误。

声明(标题中的全局范围):

GtkTreeView *treeview;
GtkTreeModel *model;
GtkTreeIter iter;
GtkListStore *store;
GtkTreeSelection *selector;
GtkMenuItem *delete_row_item;

初始化树相关结构:

//Load tree and list related structures.
treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
selector = GTK_TREE_SELECTION(gtk_builder_get_object(builder, "treeview-selection"));
store = GTK_LIST_STORE(gtk_builder_get_object(builder,"liststore"));
//Set the tree model
model = gtk_tree_view_get_model(treeview);

从glade文件中获取删除菜单项并将其连接到函数:

delete_row_item = gtk_builder_get_object(builder, "delete");
g_signal_connect(delete_row_item, "activate", G_CALLBACK(delete_row), NULL);

1 个答案:

答案 0 :(得分:0)

这可能与此有任何关系,但我认为值得一提:

你在玩火!全局变量很危险,特别是在与事件有关的环境中,例如gtk。

您存储在全局变量中的参数很可能会被另一个事件更改。特别危险的是iter,很可能很容易在几个地方使用。您应该在函数中使用局部变量(在每个函数中单独使用):

void delete_row()
{
    GtkTreeView *treeview;
    GtkTreeModel *model;
    GtkTreeIter iter;

    treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview"));
    selector = gtk_tree_view_get_selection(treeview);
    gtk_tree_selection_get_selected(selector, &model, &iter);
    gtk_list_store_remove(GTK_LIST_STORE(store), &iter);

}

另外,请注意您已经定义了一个列表库,以及一个可能引起混淆的模型:

 GtkTreeModel *model;
 GtkListStore *store;

两者都指向模型(liststore只是模型的特例) 不要混在一起 - 要注意!

事实上我刚刚注意到你实际上在删除功能中使用了商店和模型:

  

gtk_tree_selection_get_selected(选择器,& 型号,& iter);   gtk_list_store_remove(GTK_LIST_STORE(商店),& iter);