gtkgtk3pygtkgtk#gtk2

GTK Tree View # How to remove or hide the toggle button in column


There is defined a GTK tree view and one of the column is rendered the toggle button. Now every row is showing the toggle button, is there a way to remove or hide the toggle button from some row completely. For example I have following example

#include <gtk/gtk.h>

enum {
    COL_NUM_LIST = 0,
    COL_TOGGLE,
    COL_STRING,
    NUM_COLS
};

static GtkTreeModel*
create_and_fill_model(void) {
    GtkTreeStore *treestore;
    GtkTreeIter toplevel, child;

    treestore = gtk_tree_store_new(NUM_COLS,
            G_TYPE_STRING,
            G_TYPE_BOOLEAN,
            G_TYPE_STRING);

    /* Append a top level row and leave it empty */
    gtk_tree_store_append(treestore, &toplevel, NULL);
    gtk_tree_store_set(treestore, &toplevel,
            COL_NUM_LIST, "1",
            COL_TOGGLE, TRUE,
            COL_STRING, "Foo Bar",
            -1);

    /* Append a second top level row, and fill it with some data */
    gtk_tree_store_append(treestore, &toplevel, NULL);
    gtk_tree_store_set(treestore, &toplevel,
            COL_NUM_LIST, "2",
            COL_TOGGLE, TRUE,
            COL_STRING, "",  // empty
            -1);

    /* Append a child to the second top level row, and fill in some data */
    gtk_tree_store_append(treestore, &child, &toplevel);
    gtk_tree_store_set(treestore, &child,
            COL_NUM_LIST, "3",
            COL_TOGGLE, FALSE,
            COL_STRING, "Not needed toggle button here",
            -1);

    return GTK_TREE_MODEL(treestore);
}

void string_cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer,
        GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) {
    char *string;

    gtk_tree_model_get(model, iter, COL_STRING, &string, -1);
    g_object_set(renderer, "text", string, NULL);
}

void toggle_cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer,
        GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) {

    int bol;
    gtk_tree_model_get(model, iter, COL_TOGGLE, &bol, -1);

    if (bol == 0)
        g_object_set(renderer, "active", NULL, NULL);   // Can we somehow null or remove toggle button
    else
        g_object_set(renderer, "active", TRUE, NULL);
}

static GtkWidget*
create_view_and_model(void) {
    GtkTreeViewColumn *col;
    GtkCellRenderer *renderer;
    GtkWidget *view;
    GtkTreeModel *model;

    view = gtk_tree_view_new();

    // --- Column #1 ---
    col = gtk_tree_view_column_new();

    gtk_tree_view_column_set_title(col, "#");

    /* pack tree view column into tree view */
    gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);

    // toggle renderer
    renderer = gtk_cell_renderer_text_new();

    /* pack cell renderer into tree view column */
    gtk_tree_view_column_pack_start(col, renderer, TRUE);

    gtk_tree_view_column_add_attribute(col, renderer, "text", COL_NUM_LIST);


    // --- Column #2 ---

    col = gtk_tree_view_column_new();

    gtk_tree_view_column_set_title(col, "Toggle");

    /* pack tree view column into tree view */
    gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);

    // toggle renderer
    renderer = gtk_cell_renderer_toggle_new();

    /* pack cell renderer into tree view column */
    gtk_tree_view_column_pack_start(col, renderer, TRUE);

    gtk_tree_view_column_set_cell_data_func(col, renderer,
            toggle_cell_data_func, NULL, NULL);

    // --- Column #3 ---

    col = gtk_tree_view_column_new();

    gtk_tree_view_column_set_title(col, "String");

    /* pack tree view column into tree view */
    gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);

    // text renderer
    renderer = gtk_cell_renderer_text_new();

    /* pack cell renderer into tree view column */
    gtk_tree_view_column_pack_start(col, renderer, TRUE);

    gtk_tree_view_column_set_cell_data_func(col, renderer,
            string_cell_data_func, NULL, NULL);

    model = create_and_fill_model();

    gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);

    g_object_unref(model); /* destroy model automatically with view */

    gtk_tree_selection_set_mode(
            gtk_tree_view_get_selection(GTK_TREE_VIEW(view)),
            GTK_SELECTION_NONE);

    return view;
}

int main(int argc, char **argv) {
    GtkWidget *window;
    GtkWidget *view;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "delete_event", gtk_main_quit, NULL); /* dirty */

    view = create_view_and_model();

    gtk_container_add(GTK_CONTAINER(window), view);

    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}

Compiled and run with GTK 3 , it creates following windows

enter image description here

So, I don't need toggle button at #3 leave of tree. How can I hide it.

P.S : I know that using GTK, I can set the state of button to disable or inconsistent, but can I completely hide it?


Solution

  • You could probably revise the properties you are setting via the "g_object_set" function as in the following code snippet.

    void toggle_cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *renderer,
                               GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
    {
    
        int bol;
        gtk_tree_model_get(model, iter, COL_TOGGLE, &bol, -1);
    
        if (bol == 0)
            g_object_set(renderer, "visible", NULL, NULL);   // Can we somehow null or remove toggle button
        else
        {
            g_object_set(renderer, "visible", TRUE, "active", TRUE, NULL);
        }
    }
    

    For the toggle button that should not appear, I utilized the "visible" property in lieu of the "active" property. That yielded the following sample image.

    Hidden Button

    See if that helps.

    Regards.