Reputation: 608
I'm having a simple dialog with a table with 2 columns, one of which is a check box. I have added a GtkCellRendererToggle but that one is not clickable. I have added a onToggle-function which is never called, it seems. The cell renderer is activatable and I have added a call to activate it a second time in the C code to be on the safe side but nothing helps. What am I doing wrong? Here's the code:
void
on_button_delete_files_click (GtkTreeSelection * widget, gpointer user_data)
{
GtkDialog * dialog = NULL;
GtkWidget * file_choser;
char * msg = NULL;
GtkListStore * liststore = NULL;
GtkTreeIter iter;
GDir * dir = NULL;
char * filename = NULL;
if (!builder_delete_files_dialog) {
GError * error = NULL;
builder_delete_files_dialog = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder_delete_files_dialog, "deletedlg.glade", &error)) {
g_warning ("%s", error->message);
g_free (error);
exit (1);
}
}
//
// Get list store
//
liststore = GTK_LIST_STORE (gtk_builder_get_object (builder_delete_files_dialog, "podcast_file_liststore"));
//gtk_list_store_clear (liststore);
//
// Add all files
//
dir = g_dir_open (download_directory, 0, NULL);
if (NULL == dir) {
}
while (NULL != (filename = g_dir_read_name (dir))) {
if (NULL == g_strrstr (filename, ".mp3"))
continue;
gtk_list_store_append(liststore, &iter);
gtk_list_store_set (liststore, &iter,
TO_BE_DELETED, FALSE,
FILENAME, filename,
-1);
}
//
// nice try since stuff is not activatable
//
GtkCellRendererToggle * toggle = GTK_CELL_RENDERER_TOGGLE(gtk_builder_get_object (builder_delete_files_dialog, "cellrenderertoggle1"));
gtk_cell_renderer_toggle_set_activatable (toggle, TRUE);
dialog = GTK_WIDGET(gtk_builder_get_object (builder_delete_files_dialog, "dialog_delete_files"));
int rc = gtk_dialog_run (GTK_DIALOG(dialog));
switch (rc) {
case GTK_RESPONSE_OK:
case GTK_RESPONSE_CANCEL:
default:
break;
}
gtk_widget_hide (dialog);
__error:
FREE_POINTER(g_dir_close, dir);
}
void on_toggle_renderer_click (GtkCellRendererToggle * cell, char * tree_path, gpointer data)
{
g_print ("=====> Dingens clicked !!! <=====\n");
GtkTreeModel *model = (GtkTreeModel *)data;
GtkTreeIter iter;
GtkTreePath *path = gtk_tree_path_new_from_string (tree_path);
gboolean fixed;
/* get toggled iter */
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter, TO_BE_DELETED, &fixed, -1);
/* do something with the value */
fixed ^= 1;
/* set new value */
gtk_list_store_set (GTK_LIST_STORE (model), &iter, TO_BE_DELETED, fixed, -1);
/* clean up */
gtk_tree_path_free (path);
}
And here's the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkImage" id="imageApply">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-apply</property>
</object>
<object class="GtkImage" id="imageDelete">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-delete</property>
</object>
<object class="GtkListStore" id="podcast_file_liststore">
<columns>
<!-- column-name TO_BE_DELETED -->
<column type="gboolean"/>
<!-- column-name FILENAME -->
<column type="gchararray"/>
<!-- column-name < -->
<column type="< Neue Spalte definieren >"/>
</columns>
</object>
<object class="GtkDialog" id="dialog_delete_files">
<property name="width_request">320</property>
<property name="height_request">300</property>
<property name="can_focus">False</property>
<property name="resizable">False</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btnDelete">
<property name="label" translatable="yes">Delete Selected</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">imageDelete</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnClose">
<property name="label" translatable="yes">Close</property>
<property name="name">btnClose</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">imageApply</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="file_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="model">podcast_file_liststore</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">Delete</property>
<child>
<object class="GtkCellRendererToggle" id="cellrenderertoggle1">
<signal name="toggled" handler="on_toggle_renderer_click" object="podcast_file_liststore" swapped="no"/>
</object>
<attributes>
<attribute name="active">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<property name="title" translatable="yes">File name</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-5">btnDelete</action-widget>
<action-widget response="-6">btnClose</action-widget>
</action-widgets>
</object>
</interface>
Again: The onToggle-Event handler is not being called when I click a check box. This makes me think that the cell is somehow not active.
Many thanks for every hint. Greets Kai
Upvotes: 3
Views: 901
Reputation: 3
I found this question when searching for how to toggle the checkboxes in a GtkTreeView. For those in the same boat, clicking on the checkbox in the rendered tree view will not automatically toggle the box, but it will emit the "toggled" signal. Connect this signal to a callback function and in that function do whatever functionality should happen when the row is toggled.
/* Toggle callback */
void toggle_row(GtkCellRendererToggle *cell_render, gchar *path,
gpointer tree_view)
{
GtkTreeModel *model;
GtkTreeIter iter;
GValue toggle_state = G_VALUE_INIT;
g_value_init(&toggle_state, G_TYPE_INT);
model = gtk_tree_view_get_model(tree_view);
if(gtk_tree_model_get_iter_from_string(model, &iter, path))
{
if(gtk_cell_renderer_toggle_get_active(cell_renderer))
{
printf("Active\n");
g_value_set_int(&toggle_state, 0);
gtk_tree_store_set_value(GTK_TREE_STORE(model), &iter, IN_COL_TICK,
&toggle_state);
}
else
{
printf("Inactive\n");
g_value_set_int(&toggle_state, 1);
gtk_tree_store_set_value(GTK_TREE_STORE(model), &iter, IN_COL_TICK,
&toggle_state);
}
}
}
/* In the tree view creation function */
{
...
GtkTreeStore *tree_store;
GtkWidget *tree_view;
GtkCellRenderer *render;
GtkTreeViewColumn *column;
...
tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_store));
render = gtk_cell_renderer_toggle_new();
column = gtk_tree_view_column_new();
gtk_tree_view_column_pack_start(column, render, FALSE);
/* connect the active signal to the column in your model that stores
the checkbox state */
gtk_tree_view_column_add_attribute(column, render, "active",
CHECKBOX_COLUMN);
/* Give the callback the tree view
g_signal_connect(render, "toggled", G_CALLBACK(toggle_row), tree_view);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
...
}
Upvotes: 0
Reputation: 19375
I got it working by making the GtkCellRendererToggle 'activatable' - ie adding the 'activatable' property with value True. – alexmurray
Upvotes: 0