如何";勾选“;GTKCellRenderer切换?

如何";勾选“;GTKCellRenderer切换?,c,gtk,gtk3,C,Gtk,Gtk3,我想一个简单的复选框,以“检查”当我点击它,但我发现这是非常棘手的,几乎没有在互联网上的例子 GtkTreeView *tree_view; GtkListStore *list_store; GtkTreeModelFilter *filter_model; static int populate_row_callback (void *data, int colCount, char *values[], char *colNames[]) { GtkTreeIter row_iter

我想一个简单的复选框,以“检查”当我点击它,但我发现这是非常棘手的,几乎没有在互联网上的例子

GtkTreeView *tree_view;
GtkListStore *list_store;
GtkTreeModelFilter *filter_model;

static int populate_row_callback (void *data, int colCount, char *values[], char *colNames[]) {
  GtkTreeIter row_iter;
  gtk_list_store_append (list_store, &row_iter);
  gtk_list_store_set (list_store, &row_iter, COL_DOWNLOAD, TRUE,
                                             ... // more cols
                                             -1);
  return 0;
}

void populate_grid () {
  gtk_list_store_clear (list_store);
  syn_get_data (populate_row_callback); // gets data from sqlite
}


static void activate (GtkApplication* app, gpointer user_data) {
  GtkBuilder *builder = gtk_builder_new_from_file ("window.ui");
  window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
  search_toggle = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "search_toggle"));
  search_bar = GTK_SEARCH_BAR (gtk_builder_get_object (builder, "search_bar"));
  search_entry = GTK_SEARCH_ENTRY (gtk_builder_get_object (builder, "search_entry"));
  tree_view = GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_view"));
  list_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "list_store"));
  filter_model = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (list_store), NULL));

  gtk_builder_connect_signals (builder, NULL);
  g_object_unref (builder);
  gtk_widget_show_all (window);

  populate_grid ();
  gtk_tree_model_filter_set_visible_func (filter_model, search_filter_func, NULL, NULL);
  gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (filter_model));

  gtk_main ();
}

void download_toggled (GtkCellRendererToggle *cell, gchar *path_string, gpointer user_data) {
  GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
  GtkTreePath *path = gtk_tree_path_new_from_string (path_string);

  GtkTreeIter rowIter;
  if (gtk_tree_model_get_iter (model, &rowIter, path)) {
    gboolean checked = gtk_cell_renderer_toggle_get_active (cell);
    // gtk_cell_renderer_toggle_set_active (cell, !checked); // effects every row!

    gtk_list_store_set (list_store, &rowIter, 0, !checked, -1); // causes runtime critical warning
  }
}
我还尝试在同一个处理程序中使用
GtkListStore

gtk_list_store_set (list_store, &rowIter, 0, !checked, -1);
但这不起作用,我得到:
Gtk-CRITICAL**:Gtk\u-list\u-store\u-set\u-valist:断言“iter\u有效(iter,list\u-store)”失败


这是因为
Iter
rowIter不是使用row_存储获取的,但是,我不能使用它,因为它没有get方法…

您的GtkListStore嵌入到GtkTreeModelFilter中,因此您创建的任何gtktreepath和gtktreeiter都将特定于GtkTreeModelFilter。为了能够修改基础GtkTreeModel,必须使用函数将GtkTreeModel过滤器的GtkTreeIter转换为基础GtkListStore的GtkTreeIter。在原始代码的
download\u toggled()
中的if块内调用它


如果将GtkTreeModelSort添加到等式中,同样适用。如果您同时使用这两个函数,您必须以正确的顺序为这两个函数调用等价的
iter\u to\u child\u iter
函数,就像一层一层地剥洋葱皮一样。

您是否尝试过使用
gtk\u tree\u model\u get\u iter\u from\u string()
并直接传递模型,而不使用
gtk\u tree\u view\u get\u model()
?这些是我在你的代码和我的代码之间看到的唯一区别,它们保证会工作。仅供参考,我的代码就是这样工作的:
gtk_tree_model_get(gtk_tree_model(model),&rowIter,0,&checked,-1);gtk_列表存储集(gtk_列表存储(型号),&rowIter,0,!选中,-1)
@hidefromkgb是的,我在一个stackoverflow问题上看到了类似的代码,但它对我不起作用,因为我在toggle函数中传递了不同的参数集。请把你的答案全部贴出来。好的。当我回家的时候,我会把一个简单的例子放在一起。你能展示第二个片段的完整代码吗?如果它在
If
块内运行,那么就没有理由认为iter无效。。。