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)

{

Pages: ← previous Ctrl next
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

© Copyright © 2002-2006 Murray Cumming. License: GNU FDL