函数gtk_cell_renderer_toggle_set_active无法正常工作

时间:2013-08-12 06:15:47

标签: gtk gtk3

我想在树视图中放置一个Checkbox。 当我点击Checkbox时,它应该是ckeck。但Checkbox一直没有被检查。 我用C和GTK3编写了一个示例代码:

#include <gtk/gtk.h>

GtkTreeModel* create_model ()
{
    GtkTreeIter gti;
    GtkListStore *gls = gtk_list_store_new ( 1, G_TYPE_BOOLEAN );   
    gtk_list_store_append ( gls, &gti );
    gtk_list_store_set ( gls, &gti, 0, FALSE, -1 );
    return GTK_TREE_MODEL ( gls );
}

void check ( GtkCellRendererToggle *cell )
{
    int active = gtk_cell_renderer_toggle_get_active ( cell );
    g_print ( "%d\n", active );
    if ( active )
    {
        //fail
        gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE ( cell ), FALSE );
    }
    else
    {
        //fail
        gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE ( cell ), TRUE) ;
    }
    return;
}

int main ( int argc, char *argv[] )
{
    gtk_init ( &argc, &argv );
//window
    GtkWidget *window_main = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
//tree view
    GtkWidget *treeview = gtk_tree_view_new_with_model ( create_model ()    );
//cell_renderer_toggle
    GtkCellRenderer *cell = gtk_cell_renderer_toggle_new ();

    gtk_tree_view_append_column ( GTK_TREE_VIEW ( treeview ), gtk_tree_view_column_new_with_attributes ( "test", cell, "active",  0, NULL ) );
    g_signal_connect ( cell, "toggled", G_CALLBACK ( check ), NULL );

    gtk_container_add ( GTK_CONTAINER ( window_main ), treeview );  
    gtk_widget_show_all ( window_main );
    gtk_main();
    return 0;
}

函数gtk_cell_renderer_toggle_set_active调用失败,并且未将单元格设置为活动状态。 请帮我修改我的代码。

1 个答案:

答案 0 :(得分:1)

通过

的召唤
    gtk_tree_view_column_new_with_attributes ("test", cell, "active", 0, NULL);

将列的任何行中每个单元格渲染器的"active"属性绑定到相关数据模型的第一列中的值。虽然任何GtkCellRendererToggle实例的状态由其自己的属性表示,但其"active"属性同时反映数据模型中的相应值。

如果通过gtk_cell_renderer_toggle_set_active激活单个单元格渲染器,则只需设置特定"active"实例的GtkCellRendererToggle属性。遗憾的是,实例不了解数据模型,因为它表示一个值,因此无法访问它。这意味着在树视图的下一次绘制中,"active"属性再次与数据模型中的相关值对应。您的更改只是被覆盖。

尽管如此,您仍然可以安全地设置未连接到数据模型的单元格渲染器的所有其他属性。我在我的例子中包含了一个例子。

这意味着您的回调必须更改数据模型中的值,而不是更改单元格渲染器的属性。

您的示例代码的附加修改说明了我所描述的内容


#include <gtk/gtk.h>

GtkListStore *
create_model ()
{
    GtkTreeIter gti;
    GtkListStore *gls;

    gls = gtk_list_store_new (1, G_TYPE_BOOLEAN);
    gtk_list_store_append (gls, &gti);
    gtk_list_store_set (gls, &gti, 0, TRUE, -1);

    return gls;
}

void
check (GtkCellRendererToggle * cell, gchar * path, GtkListStore * model)
{
    GtkTreeIter iter;
    gboolean active;

    active = gtk_cell_renderer_toggle_get_active (cell);

    gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (model), &iter, path);

    if (active) {
        gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(cell), 0, 0);
        gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, FALSE, -1);
    }
    else {
        gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(cell), 0.5, 0.5);
        gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, TRUE, -1);
    }
}

int
main (int argc, char *argv[])
{

    GtkTreeViewColumn *column;
    GtkWidget *window_main;
    GtkWidget *treeview;
    GtkCellRenderer *cell;
    GtkListStore *store;


    gtk_init (&argc, &argv);

    store = create_model ();

    //window
    window_main = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    //tree view
    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));

    //cell_renderer_toggle
    cell = gtk_cell_renderer_toggle_new ();

    column =
        gtk_tree_view_column_new_with_attributes ("test",
                                                  cell, "active", 0, NULL);

    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);

    g_signal_connect (cell, "toggled", G_CALLBACK (check), store);
    g_signal_connect (window_main, "destroy",
                      G_CALLBACK (gtk_main_quit), NULL);

    gtk_container_add (GTK_CONTAINER (window_main), treeview);
    gtk_widget_show_all (window_main);
    gtk_main ();

    return 0;
}