Search code examples
cgtkglade

Retrieving data from GtkListStore


I have a created a GUI with a tree view in Glade. This is the XML file:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.24"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkListStore" id="liststore1">
    <columns>
      <!-- column-name column1 -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkTreeView" id="treeview1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="model">liststore1</property>
      </object>
    </child>
  </object>
</interface>

I am trying to set some data in the list and retrieve it with the following code:

#include <gtk/gtk.h>

int main(int argc, char * argv[]) {
    GtkBuilder* gtkBuilder = gtk_builder_new();
    GtkWidget* mainwin;

    gtk_init(&argc, &argv);

    gtk_builder_add_from_file(gtkBuilder, "test.glade", NULL);

    mainwin = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, "window1"));

    // set treeview data
    GtkTreeView *treeview = NULL;
    GtkTreeModel *model = NULL;
    GtkListStore *liststore = NULL;
    GtkTreeIter iter;
    gchar* data = "Hello World";
    gchar* item = NULL;

    treeview = GTK_TREE_VIEW(gtk_builder_get_object(gtkBuilder, "treeview1"));
    model = gtk_tree_view_get_model(treeview);
    liststore = GTK_LIST_STORE(model);

    gtk_list_store_append(liststore, &iter);
    gtk_list_store_set(liststore, &iter, 0, data, -1);

    gtk_tree_model_get(model, &iter, 0, item, -1);

    printf("item: %s\n", item);

    g_object_unref(G_OBJECT(gtkBuilder));

    g_signal_connect(mainwin, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    gtk_widget_show(mainwin);
    gtk_main();
}

However, the data is neither displayed in the tree view nor can I retrieve the previously inserted data. I do not know whether the data was correctly inserted into the list and/or if I am just trying to receive it the wrong way.


Solution

  • From the gtk_tree_model_get () documentation:

    Gets the value of one or more cells in the row referenced by iter . The variable argument list should contain integer column numbers, each column number followed by a place to store the value being retrieved. The list is terminated by a -1. For example, to get a value from column 0 with type G_TYPE_STRING, you would write: gtk_tree_model_get (model, iter, 0, &place_string_here, -1), where place_string_here is a gchararray to be filled with the string.

    So, you should change in your code:

    gtk_tree_model_get(model, &iter, 0, item, -1);
    

    To:

    gtk_tree_model_get(model, &iter, 0, &item, -1);
    

    Also notice:

    Returned values with type G_TYPE_OBJECT have to be unreferenced, values with type G_TYPE_STRING or G_TYPE_BOXED have to be freed. Other values are passed by value.

    So, you will need to free item, e.g. g_free (item);, after use.

    EDIT:

    The treeview has no TreeViewColumn and neither a CellRendererText.

    I've added those to your glade file:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Generated with glade 3.19.0 -->
    <interface>
      <requires lib="gtk+" version="3.0"/>
      <object class="GtkListStore" id="liststore1">
        <columns>
          <!-- column-name column1 -->
          <column type="gchararray"/>
        </columns>
      </object>
      <object class="GtkWindow" id="window1">
        <property name="can_focus">False</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"/>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                <property name="title" translatable="yes">column</property>
                <child>
                  <object class="GtkCellRendererText" id="cellrenderertext1">
                    <property name="height">40</property>
                  </object>
                  <attributes>
                    <attribute name="text">0</attribute>
                  </attributes>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </interface>
    

    It should work now:

    enter image description here