Lists 和 Trees: GtkTreeView 元件

第一章. 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;
}