ビューは実際のウィジット(TreeView)であり、これがモデル(TreeModel)のデータを表示し、ユーザーの操作に反応します。ビューはモデルの全ての列、あるいは一部だけを表示することができますし、それらを様々な方法で表示することもできます。
TreeModelオブジェクトを指定してください。これはTreeViewを生成するときに行えますし、set_model()メソッドを使うこともできます。このように:
m_TreeView.set_model(m_refListStore);
append_column()メソッドを使えば、ビューに特定のモデルの複数の列を特定の順序、特定の列タイトルで表示させるようにできます。
m_TreeView.append_column("Messages", m_Columns.m_col_text);
この単純なappend_column()オーバーライドを使った場合、TreeViewはモデルデータを適切なCellRendererで表示します。例えば、文字列と数値は単にEntryウィジットの中に表示され、真偽値はCheckButtonに表示されます。これはほとんどの場合、望ましい挙動です。これらとは違う型の列に対しては、その型を文字列表現に変換するようなコールバックを接続するか(TreeViewColumn::set_cell_data_func()を使います)、カスタ厶CellRendererクラスを派生してください。注意してほしいのは、(unsigned) short型はデフォルトではサポートされていないことです。列の型には(unsigned) intか(unsigned) longを使ってください。
ビューの列にひとつ以上のモデルの列を表示させるには、TreeView::Columnウィジットを手動で生成する必要があります。ウィジットでpack_start()を使って、モデルの列を追加してください。
それから、append_column()を使ってその列ウィジットをビューに追加します。注目してほしいのは、View::append_column()はオーバライドされていて、準備したView::Columnか、適切なView::Columnウィジットを生成するようなTreeModelColumnを受け取るようになっているところです。
以下にコード例はdemos/gtk-demo/example_stockbrowser.ccのもので、Pixbufアイコンと名前の文字列を同じ列に置いています:
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);
デフォルトのCellRendererの振る舞いは、通常は、十分なものですがもっと細かい操作が必要なときがあるかもしれません。次のコード例(demos/gtk-demo/example_treestore.cc)では、手動でCellRendererウィジットを構築し、様々な列モデルのデータを様々な外観の相で表示する方法を示しています。
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)
{
pColumn->add_attribute(pRenderer->property_active(), m_columns.alex);
pColumn->add_attribute(pRenderer->property_visible(), m_columns.visible);
pColumn->add_attribute(pRenderer->property_activatable(), m_columns.world);
さらに、CellRendererシグナルを接続してユーザーの操作を検出することができます。例えば、このように:
Gtk::CellRendererToggle* pRenderer = Gtk::manage( new Gtk::CellRendererToggle() ); pRenderer->signal_toggled().connect( sigc::bind( sigc::mem_fun(*this, &Example_TreeView_TreeStore::on_cell_toggled), m_columns.dave) );
TreeView内のセルはユーザーがその場で編集出来るように設定できます。これを行うにはTreeViewのメソッドinsert_column_editable()とappend_column_editable()を、insert_column()とappend_column()の代わりに使ってください。
これらのセルに新しい値が入力された場合、値はモデルの中に即座に格納されます。覚えておいてください。これらのメソッドは列データの型にGlib::ustring, int, long といった単純なものしかインスタンス化できないテンプレートです。
しかしながら、新しい値を即座に格納して欲しくない場合があるかもしれません。例えば、入力をある文字種や値の範囲に制限したい場合です。
これを可能にするには、まず通常のTreeViewのメソッドinsert_column()とappend_column()を使い、それからget_column_cell_renderer()を使って、列に用いられているCellRendererを取得してください。
そして、得られたCellRenderer*オブジェクトを設定したCellRedererへキャストしてください。そうすれば設定したAPIが使えるようになります。
例えば、CellRendererTextではセルのeditable属性をtrueにできます:
cell.property_editable() = true;
CellRendererToggleの方はactivatable属性が設定できます
さらに適切な"edit"シグナルを接続します。接続先は、例えば、CellRendererText::signal_edited()やCellRendererToggle::signal_toggled()です。列がひとつ以上CellRendererを持っている場合はTreeView::get_column()を使い、それからビューの列でget_cell_renderers()を呼んでください。
シグナルハンドラの中で新しい値を検査して、それがアプリケーションで適切だった場合にモデル内へ格納するようにしてください。