【问题标题】:Cannot toggle check boxes in tree view无法在树视图中切换复选框
【发布时间】:2015-02-05 20:29:00
【问题描述】:

我有一个包含 2 列的表的简单对话框,其中一个是复选框。我添加了一个 GtkCellRendererToggle,但那个是不可点击的。我添加了一个从未调用过的 onToggle 函数,似乎。 单元格渲染器是可激活的,为了安全起见,我在 C 代码中添加了第二次激活它的调用,但没有任何帮助。我究竟做错了什么? 代码如下:

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);
}

这是 XML 文件:

<?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="&lt; Neue Spalte definieren &gt;"/>
    </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>

再次:当我单击复选框时,未调用 onToggle-Event 处理程序。这让我觉得细胞不知何故不活跃。

非常感谢您的每一个提示。 问候 启

【问题讨论】:

  • 你找到答案了吗?我也面临同样的问题...
  • 不,实际上。我怀疑这是一个错误。但是与 python 相比,C 中的 glade 和 GTK 似乎不是很流行....
  • 我通过将 GtkCellRendererToggle 设置为“可激活”来使其工作 - 即添加值为 True 的“可激活”属性。

标签: c gtk3 glade gtktreeview


【解决方案1】:

我通过将 GtkCellRendererToggle 设为“可激活”来使其工作 - 即添加值为 True 的“可激活”属性。 – 亚历克斯默里

【讨论】:

    【解决方案2】:

    我在搜索如何切换 GtkTreeView 中的复选框时发现了这个问题。 对于那些在同一条船上的人,单击渲染树视图中的复选框不会自动切换框,但会发出“切换”信号。 将此信号连接到回调函数,并在该函数中执行切换行时应发生的任何功能。

    /* 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);
    
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2015-02-17
      • 2011-05-27
      • 1970-01-01
      • 2011-01-24
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多