3.4. Manipulating Row Data

Adding empty rows to a data store is not terribly exciting, so let's see how we can add or change data in the store.

gtk_list_store_set and gtk_tree_store_set are used to manipulate a given row's data. There is also gtk_list_store_set_value and gtk_tree_store_set_value, but those should only be used by people familiar with GLib's GValue system.

Both gtk_list_store_set and gtk_tree_store_set take a variable number of arguments, and must be terminated with a -1 argument. The first two arguments are a pointer to the model, and the iter pointing to the row whose data we want to change. They are followed by a variable number of (column, data) argument pairs, terminated by a -1. The column refers to the model column number and is usually an enum value (to make the code more readable and to make changes easier). The data should be of the same data type as the model column.

Here is an example where we create a store that stores two strings and one integer for each row:


  enum
  {
    COL_FIRST_NAME = 0,
    COL_LAST_NAME,
    COL_YEAR_BORN,
    NUM_COLS
  };

  GtkListStore *liststore;
  GtkTreeIter   iter;

  liststore = gtk_list_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);

  /* Append an empty row to the list store. Iter will point to the new row */
  gtk_list_store_append(liststore, &iter);

  /* Fill fields with some data */
  gtk_list_store_set (liststore, &iter,
                      COL_FIRST_NAME, "Joe",
                      COL_LAST_NAME, "Average",
                      COL_YEAR_BORN, (guint) 1970,
                      -1);

You do not need to worry about allocating and freeing memory for the data to store. The model (or more precisely: the GLib/GObject GType and GValue system) will take care of that for you. If you store a string, for example, the model will make a copy of the string and store that. If you then set the field to a new string later on, the model will automatically free the old string and again make a copy of the new string and store the copy. This applies to almost all types, be it G_TYPE_STRING or GDK_TYPE_PIXBUF.

The exception to note is G_TYPE_POINTER. If you allocate a chunk of data or a complex structure and store it in a G_TYPE_POINTER field, only the pointer value is stored. The model does not know anything about the size or content of the data your pointer refers to, so it could not even make a copy if it wanted to, so you need to allocate and free the memory yourself in this case. However, if you do not want to do that yourself and want the model to take care of your custom data for you, then you need to register your own type and derive it from one of the GLib fundamental types (usually G_TYPE_BOXED). See the GObject GType reference manual for details. Making a copy of data involves memory allocation and other overhead of course, so one should consider the performance implications of using a custom GLib type over a G_TYPE_POINTER carefully before taking that approach. Again, a custom model might be the better alternative, depending on the overall amount of data to be stored (and retrieved).