Chapter 9. The TreeView widget

# Chapter 9. The TreeView widget

The `Gtk::TreeView` widget can contain lists or trees of data, in columns.

## The Model

Each `Gtk::TreeView` has an associated `Gtk::TreeModel`, which contains the data displayed by the `TreeView`. Each `Gtk::TreeModel` can be used by more than one `Gtk::TreeView`. For instance, this allows the same underlying data to be displayed and edited in 2 different ways at the same time. Or the 2 Views might display different columns from the same Model data, in the same way that 2 SQL queries (or "views") might show different fields from the same database table.

Although you can theoretically implement your own Model, you will normally use either the `ListStore` or `TreeStore` model classes.

Reference

### ListStore, for rows

The `ListStore` contains simple rows of data, and each row has no children.

Figure 9.1. TreeView - ListStore

Reference

### TreeStore, for a hierarchy

The `TreeStore` contains rows of data, and each row may have child rows.

Figure 9.2. TreeView - TreeStore

Reference

### Model Columns

The `TreeModelColumnRecord` class is used to keep track of the columns and their data types. You add `TreeModelColumn` instances to the `ColumnRecord` and then use those `TreeModelColumns` when getting and setting the data in model rows. You will probably find it convenient to derive a new `TreeModelColumnRecord` which has your `TreeModelColumn` instances as member data.

    class ModelColumns : public Gtk::TreeModelColumnRecord
    {
    public:

      ModelColumns()
        { add(m_col_text); add(m_col_number); }

      Gtk::TreeModelColumn<Glib::ustring> m_col_text;
      Gtk::TreeModelColumn<int> m_col_number;
    };

    ModelColumns m_Columns;

You specify the `ColumnRecord` when creating the Model, like so:

    Glib::RefPtr<Gtk::ListStore> refListStore =
        Gtk::ListStore::create(m_Columns);

As a `TreeModelColumnRecord` describes structure, not data, it can be shared among multiple models, and this is preferable for efficiency. However, the instance (such as `m_Columns` here) should usually not be static, because it often needs to be instantiated after glibmm has been initialized. The best solution is to make it a lazily instantiated singleton, so that it will be constructed on-demand, whenever the first model accesses it.

### Adding Rows

Add rows to the model with the `append()`, `prepend()`, or `insert()` methods.

    Gtk::TreeModel::iterator iter = m_refListStore->append();

You can dereference the iterator to get the Row:

    Gtk::TreeModel::Row row = *iter;

#### Adding child rows

`Gtk::TreeStore` models can have child items. Add them with the `append()`, `prepend()`, or `insert()` methods, like so:

    Gtk::TreeModel::iterator iter_child =
        m_refTreeStore->append(row.children());

### Setting values

You can use the `operator[]` override to set the data for a particular column in the row, specifying the `TreeModelColumn` used to create the model.

    row[m_Columns.m_col_text] = "sometext";

### Getting values

You can use the `operator[]` override to get the data in a particular column in a row, specifiying the `TreeModelColumn` used to create the model.

    Glib::ustring strText = row[m_Columns.m_col_text];
    int number = row[m_Columns.m_col_number];

The compiler will complain if you use an inappropriate type. For instance, this would generate a compiler error:

    //compiler error - no conversion from ustring to int.
    int number = row[m_Columns.m_col_text];

### "Hidden" Columns

You might want to associate extra data with each row. If so, just add it as a Model column, but don't add it to the View.

Multiple-item widgets |  | The View