第一章. Lists 和 Trees: GtkTreeView 元件
GtkTreeView 是一個可顯示單一欄位或多重欄位的列表或樹的元件,它取代了Gtk+-1.2的GtkCList及GtkCTree元件,即使 GtkTreeView 比以前的東西還難以精通,但是一旦了解了之後大多數的應用程式的開發者不會想失去這個很有威力及彈性的功能。
本章的目的不是要提供GtkTreeView一份詳細的文件 – 那份文件可以詳閱API documentation,該篇文件可以放在本篇教學旁邊閱讀,說得洽當一點我們的目標在呈現GtkTreeView最常用的部分介紹,以及說明GtkTreeView 不同的組件及概念如何一起運作,更進一步我們常是放些光在定製的 tree models 及定製的 cell renderers上這些常常被提到到卻很少被解釋。
開發者尋找一篇不到五段的簡短的介紹來教他們所有他們需要知道的是不可能在此找到的,在作者的經驗中,開發者不了解tree view 及 model是如何運作的話一旦他們試著要修改一些範例就會碰到問題,而那些採用Model/View/Controller-設計其他工具的開法者會發現API 參考手冊用教簡要的方式提供了所有他們需要知道的資訊,當然一些不一致的地方可以直接到 運用中的範例程式碼 看。
請注意下一節的範例不需要說明GtkTreeView是如何在特別的情況下最好的使用,有很多不同的方法可以完成相同的結果,而這些範例只是顯示了那些不同的方法,所以開法者能夠決定哪一個是最適合於手上工作所使用的範例。
1.1. Hello World
如果有點不耐煩這裡有一個 treeview ‘Hello World’ 的小範例程式 (這個程式可以在 treeview-tutorial.tar.gz 這一節找到),
/* * Compile with: * gcc -o helloworld helloworld.c `pkg-config --cflags --libs gtk+-2.0` * */ #include <gtk/gtk.h> enum { COL_NAME = 0, COL_AGE, NUM_COLS } ; static GtkTreeModel * create_and_fill_model (void) { GtkListStore *store; GtkTreeIter iter; store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT); /* Append a row and fill in some data */ gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, COL_NAME, "Heinz El-Mann", COL_AGE, 51, -1); /* append another row and fill in some data */ gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, COL_NAME, "Jane Doe", COL_AGE, 23, -1); /* ... and a third row */ gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, COL_NAME, "Joe Bungop", COL_AGE, 91, -1); return GTK_TREE_MODEL (store); } static GtkWidget * create_view_and_model (void) { GtkCellRenderer *renderer; GtkTreeModel *model; GtkWidget *view; view = gtk_tree_view_new (); /* --- Column #1 --- */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Name", renderer, "text", COL_NAME, NULL); /* --- Column #2 --- */ renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, "Age", renderer, "text", COL_AGE, NULL); model = create_and_fill_model (); gtk_tree_view_set_model (GTK_TREE_VIEW (view), model); /* The tree view has acquired its own reference to the * model, so we can drop ours. That way the model will * be freed automatically when the tree view is destroyed */ g_object_unref (model); return view; } int main (int argc, char **argv) { GtkWidget *window; GtkWidget *view; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (window, "delete_event", gtk_main_quit, NULL); /* dirty */ view = create_view_and_model (); gtk_container_add (GTK_CONTAINER (window), view); gtk_widget_show_all (window); gtk_main (); return 0; } |