从 Gtk TreeStore 中删除行时出错

Error Removing Row from Gtk TreeStore

我有一个函数可以从列表存储中删除单独选择的行,但每次调用它时,我都会收到一条错误消息:

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);,它给出了同样的错误。

声明(来自 header 的全局范围):

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

这可能与此无关,但我认为值得一提:

你这是在玩火!全局变量是危险的,特别是在处理事件的环境中,例如 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(selector, &model, &iter); gtk_list_store_remove(GTK_LIST_STORE(store), &iter);