GTK Glade C - 将变量传递给函数,包括treeview

时间:2017-12-20 09:40:07

标签: c gtk glade

只能在回调函数中传递一个变量。所以我们必须建造结构。我对此很好但是如何处理Treeview和Treemodel / Liststore?

我想避免全局变量。此测试程序应获取EntryBox中显示的所选行的内容。我不知道我是否错误地制作包含Treeview的结构或者函数内部是否有错误。我得到了段错误。

处理这个问题的正确方法是什么?

#include <gtk/gtk.h>

typedef struct {
    GtkWidget *ent_date;
    GtkWidget *ent_lib;
    GtkWidget *ent_mont;
    GtkTreeView *treeview;

} app_widgets;

enum
{
    DATE_COLUMN,
    LIBELLE_COLUMN,
    MONTANT_COLUMN,
    N_COLUMN
};


void on_window_main_destroy()
{
    gtk_main_quit();
}


void on_treeview_selection1_changed (GtkTreeSelection *treeselection, app_widgets *app_wid) {

    gchar value[3];
    GtkTreeIter iter;
    GtkTreePath *path;
    //GtkTreeView *treeview = (GtkTreeView *)app_wid->treeview;
    GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app_wid->treeview)));

    gtk_tree_view_get_cursor (app_wid->treeview, &path, NULL);
    gtk_tree_model_get_iter (GTK_TREE_MODEL(store), &iter, path);
    gtk_tree_path_free (path);

    if (gtk_tree_selection_get_selected(treeselection, &store, &iter))
    {
        gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, DATE_COLUMN, &value[0], LIBELLE_COLUMN, &value[1],MONTANT_COLUMN, &value[2], -1);

    }

    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_date), value[0]);
    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_lib), value[1]);
    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_mont), value[2]);

    g_free(value);

}


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

    app_widgets *widgets = g_slice_new(app_widgets);


    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "test.glade", NULL);

    widgets->ent_date  = GTK_WIDGET(gtk_builder_get_object(builder, "entry_date"));
    widgets->ent_lib = GTK_WIDGET(gtk_builder_get_object(builder, "entry_lib"));
    widgets->ent_mont = GTK_WIDGET(gtk_builder_get_object(builder, "entry_mont"));
    widgets->treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview1"));

    gtk_builder_connect_signals(builder, NULL);

    gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(builder, "window1")));

    g_object_unref(builder);

    gtk_main();

    g_slice_free(app_widgets, widgets);
    return 0;
}

这是林间空地文件:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
  <requires lib="gtk+" version="3.12"/>
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name Date -->
      <column type="gchararray"/>
      <!-- column-name Libellé -->
      <column type="gchararray"/>
      <!-- column-name Montant -->
      <column type="gchararray"/>
    </columns>
    <data>
      <row>
        <col id="0" translatable="yes">20.05.2017</col>
        <col id="1" translatable="yes">Something - here</col>
        <col id="2" translatable="yes">30.20</col>
      </row>
      <row>
        <col id="0" translatable="yes">25.06.2017</col>
        <col id="1" translatable="yes">Something else - overthere</col>
        <col id="2" translatable="yes">24.90</col>
      </row>
      <row>
        <col id="0" translatable="yes">11.08.2017</col>
        <col id="1" translatable="yes">Third thing - lala</col>
        <col id="2" translatable="yes">5.15</col>
      </row>
    </data>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="margin_left">5</property>
    <property name="margin_right">5</property>
    <property name="margin_top">5</property>
    <property name="margin_bottom">5</property>
    <property name="window_position">center</property>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <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="treeview1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="model">liststore1</property>
                <child internal-child="selection">
                  <object class="GtkTreeSelection" id="treeview-selection1">
                    <signal name="changed" handler="on_treeview_selection1_changed" swapped="no"/>
                  </object>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                    <property name="resizable">True</property>
                    <property name="fixed_width">70</property>
                    <property name="title" translatable="yes">Date</property>
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
                      <attributes>
                        <attribute name="text">0</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                    <property name="resizable">True</property>
                    <property name="title" translatable="yes">Libellé</property>
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
                      <attributes>
                        <attribute name="text">1</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="treeviewcolumn3">
                    <property name="resizable">True</property>
                    <property name="title" translatable="yes">Montant</property>
                    <child>
                      <object class="GtkCellRendererText" id="cellrenderertext3"/>
                      <attributes>
                        <attribute name="text">2</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>
        <child>
          <object class="GtkBox" id="box2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkBox" id="box_date">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLabel" id="label1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">Date</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkEntry" id="entry_date">
                    <property name="visible">True</property>
                    <property name="can_focus">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="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkBox" id="box_lib">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLabel" id="label2">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">Lib</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkEntry" id="entry_lib">
                    <property name="visible">True</property>
                    <property name="can_focus">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="position">1</property>
              </packing>
            </child>
            <child>
              <object class="GtkBox" id="box_mont">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLabel" id="label3">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">Montant</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkEntry" id="entry_mont">
                    <property name="visible">True</property>
                    <property name="can_focus">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="position">2</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

1 个答案:

答案 0 :(得分:1)

首先,您不能使用gtk_builder_connect_signals(builder, NULL);,然后期望回调处理程序接收用户数据。

您应该已通过widgets结构:

gtk_builder_connect_signals(builder, widgets);

第二件事,你复杂的选择回调。当您致电gtk_tree_selection_get_selected时,GtkTreeSelection实例会为您提供模型。然后你必须明白最后一个函数将"not work if you use selection GTK_SELECTION_MULTIPLE"

还要注意gtk_tree_model_get应该指向char / gchar指针,然后指向模型内容的新分配副本(意味着它们必须在之后被释放)。

所以,你的代码应该是这样的:

#include <gtk/gtk.h>

typedef struct {
    GtkWidget *ent_date;
    GtkWidget *ent_lib;
    GtkWidget *ent_mont;
    GtkTreeView *treeview;

} app_widgets;

enum
{
    DATE_COLUMN,
    LIBELLE_COLUMN,
    MONTANT_COLUMN,
    N_COLUMN
};


void on_window_main_destroy()
{
    gtk_main_quit();
}


void on_treeview_selection1_changed (GtkTreeSelection *treeselection, app_widgets *app_wid) {

    gchar *a,*b,*c;
    GtkTreeIter iter;
    GtkTreeModel *model;

    if (gtk_tree_selection_get_selected(treeselection, &model, &iter))
    {
        gtk_tree_model_get(model, &iter, DATE_COLUMN, &a, LIBELLE_COLUMN, &b,MONTANT_COLUMN, &c, -1);
    }

    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_date), a);
    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_lib), b);
    gtk_entry_set_text(GTK_ENTRY(app_wid->ent_mont), c);

    g_free(a);
    g_free(b);
    g_free(c);
}


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

    app_widgets *widgets = g_slice_new(app_widgets);


    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, "test.glade", NULL);

    widgets->ent_date  = GTK_WIDGET(gtk_builder_get_object(builder, "entry_date"));
    widgets->ent_lib = GTK_WIDGET(gtk_builder_get_object(builder, "entry_lib"));
    widgets->ent_mont = GTK_WIDGET(gtk_builder_get_object(builder, "entry_mont"));
    widgets->treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview1"));

    gtk_builder_connect_signals(builder, widgets);

    gtk_widget_show(GTK_WIDGET(gtk_builder_get_object(builder, "window1")));

    g_object_unref(builder);

    gtk_main();

    g_slice_free(app_widgets, widgets);
    return 0;
}