鉴于要赶紧的能作出点成果来,container这部分就直接跳过了。。。看View了,
TreeView
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.
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.
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.
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.
Eg:
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.
Adding Rows
Add rows to the model with theappend()
,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_refListStore->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 theoperator[]
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];
"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.
The View
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);
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.
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);
Remark:
主要是三个类,第一个需要设计的是TreeModelColumnRecord,也就是设计他的一个派生类来存储每个row的各个分量,keep track of the column and its type. 这个类需要新加入类成员,即为Gtk::TreeModelColumn<type> instance_num;然后就是重写constructor, 写为add(instance_num);
然后是设计使用ModelColumn来初始化需要的Glib::RefPtr<Gtk::ListStore> refListStore = Gtk::ListStore::create(m_Columns);
而对于这样就形成了Model的大体框架,对于model中row的操作则是在使用iterator
Gtk::TreeModel::iterator iter = m_refListStore->append();
对于iterator deference则是一个Gtk::TreeModel::Row row = *iter;可以通过[]operator 对他进行操作,而这个参数则是用到 第一个类的m_Columns的成员来进行标注的。由于得到的东西既是一个Rvalue也是一个Lvalue故而可以通过这种发放进行标注。
但是对于iterator如何定位则是一个很麻烦的问题。或者说是根本不知道怎么做:
可以用iter最开始指向的为append第一个元素的地方就是开始,然后iter的指针++就会得到遍历。
到此为止,一个Model建成了,包括第一步的一个TreeModelColumnRecord的框架和用它初始化后的一个ListStore的smart ptr.
然后就是View和Model进行连接了。首先可以调用View的set_Model进行set,然后就是对于View的Column进行编写了,主要在于用.append_column_editable 或者append_column进行编辑。