关于 GtkTreeView 必须掌握的基本概念

原文地址:http://blog.linuxeden.com/index.php/7784/viewspace-5733

TreeView 可分为两个部分:一个是显示出来的,我们可以看见的文字、图像、复选框,下面称其为外部特征;一个是内部存储的数据。

先说外部特征:一个 TreeView 有多个 Column,而每个 Column 中可以有多个 CellRenderer,同时一个 CellRenderer 自身拥有多个属性。

TreeView 的内部数据由 TreeModel 决定,同时也由 TreeModel 存储,用 gtk_list_store_set () 设置一行的数据时,函数传递的值的类型与个数必须与 TreeModel 对应。

一般来说,当我们在程序中用 gtk_list_store_append () 添加一行,gtk_list_store_set () 设置该行的数据时,除了在 TreeModel 内部存储了数据外,还可以改变 TreeView 中该行的外部特征。

然而,我们可以看到的 TreeView 的外部特征:文字、图像、复选框的改变,是由于 CellRenderer 的属性改变而导致的,而不是由于 TreeModel 添加了数据而导致的。
这不是很奇怪吗?上面说 gtk_list_store_set () 可以改变 TreeView 的外部特征,现在说 TreeView 外部特征的改变不是由 gtk_list_store_set () 引起的。

其实,gtk_list_store_set () 能改变 TreeView 一行的外部显示是因为相应的数据在函数内部实现类型转换,然后传递到 CellRenderer 的属性中,而 CellRenderer 属性的改变导致了一行显示的改变。

而 TreeModel 的哪个数据与 CellRenderer 的哪个属性联系起来是由gtk_tree_view_column_set_attributes () 决定的。这个函数把 TreeModel 的某个数据与 CellRenderer 的某个属性联系起来。
当调用 gtk_list_store_set () 时,该函数在内部先把传到 TreeModel 的数据的类型转换为与 CellRenderer 属性要求的类型,然后把值赋予 CellRenderer 的属性。CellRenderer 属性的改变就导致的 TreeView 外部特征的改变了。

[@more@]下面是一个我写的例子,大家可以编译它来看看效果。
/* 关于列表的例子。
 * 编译指令为:gcc `pkg-config --cflags --libs gtk+-2.0` -Wall -g -o list list.c
 */

#include 

int
main (int argc, char *argv[])
{
  GtkWidget *main_window;
  GtkWidget *tree_view;
  GtkListStore *list_store;
  GtkTreeViewColumn *column;
  GtkCellRenderer *cell_renderer;
  GtkTreeIter tree_iter;


  gtk_set_locale ();
  gtk_init (&argc, &argv);

  main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size (GTK_WINDOW (main_window), 320, 240);
  gtk_window_set_title (GTK_WINDOW (main_window), "Main Window");


  list_store = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_UINT,
				   G_TYPE_STRING, G_TYPE_STRING,
				   G_TYPE_STRING);
  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
  gtk_widget_show (tree_view);
  gtk_container_add (GTK_CONTAINER (main_window), tree_view);


  /* 第一列:每列多个 CelRenderer,每个 CellRenderer 多个属性 */
  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, "0001");
  gtk_tree_view_column_set_resizable (column, TRUE);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
  gtk_tree_view_column_set_fixed_width (column, 100);
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);

  cell_renderer = gtk_cell_renderer_pixbuf_new ();
  gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes (column, cell_renderer, "stock-id", 0,
				       NULL);

  /* 一个 CellRenderer 的多个属性与 TreeModel 的多个数据项联系 */
  cell_renderer = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes (column, cell_renderer, "text", 1,
				       "foreground", 2, NULL);

  /* 第二列 */
  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, "0002");
  gtk_tree_view_column_set_resizable (column, TRUE);
  /* 下面注释的语句是为了试试 GtkTreeViewColumnSizing
   * 大家不妨,把注释去掉,看看结果有何不同
   */
  //  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
  //  gtk_tree_view_column_set_fixed_width (column, 100);
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);

  cell_renderer = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes (column, cell_renderer, "text", 3,
				       NULL);

  /* 第三列 */
  column = gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title (column, "0003");
  gtk_tree_view_column_set_resizable (column, TRUE);
  gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
  gtk_tree_view_column_set_fixed_width (column, 100);
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);

  cell_renderer = gtk_cell_renderer_text_new ();
  gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
  gtk_tree_view_column_set_attributes (column, cell_renderer, "text", 4,
				       NULL);


  gtk_list_store_append (list_store, &tree_iter);
  gtk_list_store_set (list_store, &tree_iter, 0, "gtk-cdrom", 1, 1000,
		      2, "red", 3, "string01..............", 4, "string02",
		      -1);
  gtk_list_store_append (list_store, &tree_iter);
  gtk_list_store_set (list_store, &tree_iter, 0, "gtk-help", 1, 2000,
		      2, "green", 3, "string11", 4, "string12", -1);

  g_signal_connect (G_OBJECT (main_window), "destroy",
		    G_CALLBACK (gtk_main_quit), NULL);

  gtk_widget_show_all (main_window);

  gtk_main ();

  return 0;
}

终端运行后显示:

$./list



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值