如何"check" GtkCellRendererToggle?

How to "check" GtkCellRendererToggle?

我想要一个简单的复选框 "check" 当我点击它时,但我发现这非常棘手,互联网上几乎没有示例!

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_list_store_set_valist: assertion 'iter_is_valid (iter, list_store)' failed

这是因为 Iter rowIter 不是使用 row_store 获取的,但话又说回来,我无法使用它获取它,因为它没有 get 方法...

您的 GtkListStore 嵌入在 GtkTreeModelFilter 中,因此您创建的任何 GtkTreePaths 和 GtkTreeIters 都将特定于 GtkTreeModelFilter。为了能够修改底层 GtkTreeModel,您必须使用 gtk_tree_model_filter_convert_iter_to_child_iter() 函数将 GtkTreeModelFilter 的 GtkTreeIter 转换为底层 GtkListStore 的 GtkTreeIter。在原始代码的 download_toggled().

的 if 块内调用它

如果您将 GtkTreeModelSort 添加到等式中,同样适用。如果您同时使用两者,则必须以正确的顺序为两者调用等效的 iter_to_child_iter 函数——这就像一层一层地剥洋葱。