如何“检查”GtkCellRendererToggle?

时间:2018-02-09 15:04:36

标签: 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;
  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

这是因为没有使用row_store获取Iter rowIter,但是再次,我无法使用它获取它,因为它没有get方法......

1 个答案:

答案 0 :(得分:2)

您的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函数 - 它就像是逐层剥洋葱。