Programming with gtkmm (chapters 8-9)
Translations of this material:
- into Russian: Программирование с gtkmm (Главы 8-9). 99% translated in draft. Almost done, let's finish it!
-
Submitted for translation by lynx 25.03.2010
Text
8. The TreeView widget
The Gtk::TreeView widget can contain lists or trees of data, in columns.
* 8.1. The Model
* 8.2. The View
* 8.3. Iterating over Model Rows
* 8.4. The Selection
* 8.5. Sorting
* 8.6. Drag and Drop
* 8.7. Popup Context Menu
* 8.8. Examples
8.1. 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
* 8.1.1. ListStore, for rows
* 8.1.2. TreeStore, for a hierarchy
* 8.1.3. Model Columns
* 8.1.4. Adding Rows
* 8.1.5. Setting values
* 8.1.6. Getting values
* 8.1.7. "Hidden" Columns
8.1.1. ListStore, for rows
The ListStore contains simple rows of data, and each row has no children.
Figure 8-1 TreeView - ListStore
Reference
8.1.2. TreeStore, for a hierarchy
The TreeStore contains rows of data, and each row may have child rows.
Figure 8-2 TreeView - TreeStore
Reference
8.1.3. 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);
Note that the instance (such as m_Columns here) should usually not be static, because it often needs to be instantiated after glibmm has been instantiated.
8.1.4. 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;
* 8.1.4.1. Adding child rows
8.1.4.1. 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_refListStore->append(row.children());
8.1.5. 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";
8.1.6. 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];
8.1.7. "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.
8.2. The View
The View is the actual widget (Gtk::TreeView) that displays the model (Gtk::TreeModel) data and allows the user to interact with it. The View can show all of the model's columns, or just some, and it can show them in various ways.
Reference
* 8.2.1. Using a Model
* 8.2.2. Adding View Columns
* 8.2.3. More than one Model Column per View Column
* 8.2.4. Specifying CellRenderer details
* 8.2.5. Editable Cells
8.2.1. Using a Model
You can specify a Gtk::TreeModel when constructing the Gtk::TreeView, or you can use the set_model() method, like so:
m_TreeView.set_model(m_refListStore);
8.2.2. Adding View Columns
You can use the append_column() method to tell the View that it should display certain Model columns, in a certain order, with a certain column title.
m_TreeView.append_column("Messages", m_Columns.m_col_text);
When using this simple append_column() override, the TreeView will display the model data with an appropriate CellRenderer. For instance, strings and numbers are shown in a simple Gtk::Entry widget, and booleans are shown in a Gtk::CheckButton. This is usually what you need. For other column types you must either connect a callback that converts your type into a string representation, with TreeViewColumn::set_cell_data_func(), or derive a custom CellRenderer. Note that (unsigned) short is not supported by default - You could use (unsigned) int or (unsigned) long as the column type instead.
8.2.3. More than one Model Column per View Column
To render more than one model column in a view column, you need to create the TreeView::Column widget manually, and use pack_start() to add the model columns to it.
Then use append_column() to add the view Column to the View. Notice that Gtk::View::append_column() is overridden to accept either a prebuilt Gtk::View::Column widget, or just the TreeModelColumn from which it generates an appropriate Gtk::View::Column widget.
Here is some example code from demos/gtk-demo/example_stockbrowser.cc, which has a pixbuf icon and a text name in the same column:
Gtk::TreeView::Column* pColumn =
Gtk::manage( new Gtk::TreeView::Column("Symbol") );
// m_columns.icon and m_columns.symbol are columns in the model.
// pColumn is the column in the TreeView:
pColumn->pack_start(m_columns.icon, false); //false = don't expand.
pColumn->pack_start(m_columns.symbol);
m_TreeView.append_column(*pColumn);
8.2.4. Specifying CellRenderer details
The default CellRenderers and their default behaviour will normally suffice, but you might occasionally need finer control. For instance, this example code from demos/gtk-demo/example_treestore.cc, manually constructs a Gtk::CellRenderer widget and instructs it to render the data from various model columns through various aspects of its appearance.
Gtk::CellRendererToggle* pRenderer =
Gtk::manage( new Gtk::CellRendererToggle() );
int cols_count = m_TreeView.append_column("Alex", *pRenderer);
Gtk::TreeViewColumn* pColumn = m_TreeView.get_column(cols_count-1);
if(pColumn)
{
© Copyright © 2002-2006 Murray Cumming. License: GNU FDL
