Table of Contents
The Gtk::TreeView widget can contain lists or trees of
data, in columns.
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.
The ListStore contains simple rows of data, and each row
has no children.
The TreeStore contains rows of data, and each row may
have child rows.
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.
Add rows to the model with the append(),
prepend(), or insert() methods.
auto iter = m_refListStore->append();
You can dereference the iterator to get the Row:
auto row = *iter;
You can use the operator[] overload 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";
You can use the operator[] overload to get the data in a
particular column in a row, specifying the
TreeModelColumn used to create the model.
auto strText = row[m_Columns.m_col_text]; auto 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];