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