在GTK+的所有構(gòu)件(widget)中,GtkTreeView算是比較難的一個了,做一個完整的GtkTreeView要牽涉到不少其他的構(gòu)件或?qū)ο?,對于初次使?/font>GtkTreeView的朋友來說,可能有點難度,因此我就我所知道的結(jié)合GTK+ API手冊來給初來乍到的朋友略講一下。希望對正在使用Gtk+的朋友有所幫助。
你可以在這里下載源代碼。
這是測試程序執(zhí)行的界面。

下面我們就來講解如何使用GtkTreeView構(gòu)件
一、MVC
首先應(yīng)該介紹的是MVC這個模式,Model/View/Controller(模式/視圖/控制器),GtkTreeView就是按照這樣的結(jié)構(gòu)來設(shè)計的。這樣的好處是,讓數(shù)據(jù)和視圖進(jìn)行分離,同一份數(shù)據(jù)可以設(shè)計不同的視圖來顯示。如同一份數(shù)據(jù),我可以在一個界面中用條狀圖來顯示,同時又可以用曲線來顯示。當(dāng)你更新你的數(shù)據(jù)的時候,視圖就會自動更新來顯示你的數(shù)據(jù)變化,所以這部分工作就是控制器來完成的了。之所以要講MVC設(shè)計模式的原因就是,我們的GtkTreeView構(gòu)件就是這么來設(shè)計的。所以先了解了這個再來學(xué)GtkTreeView,理解就容易多了。
二、GtkTreeView的組成
上面我都說了,要使用GtkTreeView要牽涉到其他不少的構(gòu)件或?qū)ο?,因此下面我們就來看一下在使?/font>GtkTreeView時我們一共需要哪些構(gòu)件或?qū)ο蟆?/font>
1,GtkTreeView -- 樹視圖
2,GtkTreeViewColumn -- 列視圖
3,GtkCellRenderer -- 渲染器
4,GtkTreeModel -- 樹模式(樹狀or鏈表)
三、創(chuàng)建一個樹視圖
3.1 第一步:創(chuàng)建一個模式
Gtk+提供了兩種簡單的模式,一個是GtkListStore,一個是GtkTreeStore。如果你對模式理解還有一些困難的話,其實我們完全可以簡單的將GtkListStore和GtkTreeStore理解成數(shù)據(jù)庫,它們就是存放我們數(shù)據(jù)的地方。一個是存放鏈?zhǔn)降臄?shù)據(jù),一個是存放樹狀的數(shù)據(jù)。我們可以通過下面的函數(shù)來創(chuàng)建一個模式(數(shù)據(jù)庫);
GtkListStore *store;
store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
這個函數(shù)創(chuàng)建一個了一個鏈?zhǔn)降哪J?,這個鏈表具有兩列。它們分別具有字符串類型和布爾類型,典型的用法我們是不會直接使用2來標(biāo)明這個鏈表的列數(shù)的。我們根據(jù)Gtk+api手冊提供的方法,創(chuàng)建一個模式更好的方法是按照下面的方式來創(chuàng)建:
enum{
MYID_COLUMN,
TITLE_COLUMN,
AUTHOR_COLUMN,
STATUS_COLUNM,
NBR_COLUMNS
};
store = gtk_list_store_new(NBR_COLUMNS, /* NBR_COLUMNS = 4 */
G_TYPE_INT,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_FLOAT);
3.1 第二步:向模式(數(shù)據(jù)庫)中添加數(shù)據(jù)
當(dāng)我們創(chuàng)建好了我們的模式之后,我們就可以向其中添加數(shù)據(jù)了,我們可以通過下面的函數(shù)和方法來向我們的模式中添加數(shù)據(jù):
GtkTreeIter iter; /* 迭代器 */
gtk_tree_store_append(store, &iter, NULL); /* 獲取插入的位置 */
gtk_tree_store_set(store, &iter,
MYID_COLUMN, 1,
TITLE_COLUMN, "美麗的大草原",
AUTHOR_COLUMN, "甲A",
-1);
注意:最后一個參數(shù)是-1,因為gtk_tree_store_set()這個函數(shù)是一個變參數(shù)函數(shù),也就是說參數(shù)的個數(shù)可以改變的,因此需要一個-1來標(biāo)志參數(shù)的結(jié)束。通過上面的語句我們就向模式中添加了一行數(shù)據(jù)了。可能你會問iter是做什么的,從字面以上我們可以讀成“迭代器”,也正如它的意思(其實我們不用管那么多),不用知道GtkTreeIter內(nèi)部結(jié)構(gòu)是怎么樣的,我們只需把它看作用來標(biāo)志store的某一行的一個數(shù)據(jù)就可以了。通過gtk_tree_store_append這個函數(shù),我們就得到了我們下一個可以插入數(shù)據(jù)的位置是什么了,iter就標(biāo)志了這個位置。我們還可以繼續(xù)通過這兩個函數(shù),不斷的望模式中添加數(shù)據(jù)。在gtk_tree_store_append的第三個參數(shù)為NULL表示獲取頂層的迭代器iter.我們也可以獲取某一迭代器的迭代器。如:
gtk_tree_store_append (store, &iter1, NULL); /* 獲取頂層的迭代器iter */
gtk_tree_store_set (store, &iter1,
TITLE_COLUMN, "我的分類1",
AUTHOR_COLUMN, "",
CHECKED_COLUMN, FALSE,
-1);
gtk_tree_store_append (store, &iter2, &iter1); /* 獲取子迭代器 */
gtk_tree_store_set (store, &iter2,
TITLE_COLUMN, "我的標(biāo)題1",
-1);
gtk_tree_store_append (store, &iter2, &iter1);
gtk_tree_store_set (store, &iter2,
TITLE_COLUMN, "我的標(biāo)題2",
-1);
...
這里我就沒有編寫子iter用法的列子了。關(guān)心的同學(xué)可以自己去查閱GTK+API手冊,經(jīng)過上面的講解應(yīng)該不難了
3.2 創(chuàng)建一個視圖
當(dāng)我們創(chuàng)建完成我們的模式(數(shù)據(jù)庫)創(chuàng)建之后,我們就可以創(chuàng)建一個視圖來顯示它了。這就要用到我們的GtkTreeView視圖了。
GtkWidget* tree;
tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
然后我們定義這個視圖的列,我們需要用到一個 GtkTreeViewColumn 的對象了
GtkCellRenderer *renderer;/* 渲染器 */
GtkTreeViewColumn *column;
renderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(renderer), "foreground", "red", NULL);
column = gtk_tree_view_column_new_with_attributes("編號",
renderer,
"text", AUTHOR_COLUMN,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
上面的幾條語句就定義了一個列對象了,并且把這個列對象與模式的第MYID_COLUMN列聯(lián)系起來了,然后我們將這個列添加到我們的tree視圖中。按照同樣的方式我們就可以添加其他更多的列了。
到了這一步我們也算了解了GtkTreeView的創(chuàng)建的過程了,最后我們再為每個行添加一個行選擇信號處理函數(shù)就比較完美了。
3.3 添加行選擇信號
大多數(shù)的應(yīng)用程序不僅僅只需要處理顯示數(shù)據(jù)就完成了,而且還需要獲取用戶的輸入信號,為了達(dá)到這個目的,我們使用"changed"信號來與用戶的選擇信號進(jìn)行關(guān)聯(lián)起來。
/* changed信號處理函數(shù)原型 */
static void tree_selection_changed(GtkTreeSelection *selection, gpointer data);
/* 設(shè)置選擇對象*/
GtkTreeSelection *select;
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
g_signal_connect(G_OBJECT(select), "changed",
G_CALLBACK(tree_selection_changed),
NULL);

三、總結(jié)
為了給上面的講解有一個更加直觀的了解,我為其寫了一個簡單的用例,在這個用例中,我設(shè)計了4列其他們之間完全沒有任何的聯(lián)系,只是為了給大家演示某種對象或控件的用法,例如我把"編號"列的字體設(shè)為了紅色,是為了讓大家了解“渲染器”的用法,給程序添加一個進(jìn)度條,是為了給大家演示在GtkTreeView中進(jìn)度條,該怎么使用,只要在加上一個計時器,進(jìn)度條就可以動起來了。希望這篇文章對各位學(xué)習(xí)GtkTreeView的同學(xué)有所幫助,由于代碼有點長度,因此沒有列在文章中,但是在文章的開頭我已經(jīng)提供了下載源代碼的連接。其中包含一個GtkTreeView.c的文件,和Makefile文件,以及一個已經(jīng)編譯過的可直接運(yùn)行的GtkTreeView程
序,如果點擊不能運(yùn)行,請修改該程序的屬性以允許該程序執(zhí)行。
代碼預(yù)覽:

注意:如果你要親自編譯,請確保你已經(jīng)安裝了Gtk庫文件,安裝方法sudo apt-get install libgtk+-2.0。如果安裝不了,請換一個更新源。有什么問題可以給我留言,如果你無法下載源代碼,請留下你的郵箱,我將直接發(fā)送到你的郵箱里面去。