阅读 223

GTK treeview原理及使用方法解析

这篇文章主要介绍了GTK treeview原理及使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

GtkTreeView 构件是一个高级的构件,利用他你就可以制作出漂亮的普通列表或者是树状的列表。这个构件里可以包含一或者多行。他的构架呢?正是采用了大名鼎鼎的MVC (Model View Controller) 设计框架。也就是说数据和显示方式是进行了一种分离的操作。

于是在GtktreeView构件中确实还有着其他几个独立的对象结构(objects)。

其中 GtkCellRenderer 就决定了在GtkTreeViewColumn. 中的数据究竟是如何来进行显示呈现的。

GtkListStore 和GtkTreeStore 的功能为体现模型(model)的作用。

也就是说他们是用来处理和分析将要在GtkTreeView显示的数据的。

GtkTreeIter 则是一个数据结构被用于在GtkTreeView构件中,对行中的数据进行操作。

GtkTreeSelection 则是用来处理选项的。

效果如下

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <gtk/gtk.h>
 
enum
{
  LIST_ITEM = 0,
  N_COLUMNS
};
 
void init_list(GtkWidget *list)
{
 
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *store;
 
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes("List Items",
       renderer, "text", LIST_ITEM, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
 
  store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING);
 
  gtk_tree_view_set_model(GTK_TREE_VIEW(list),
              GTK_TREE_MODEL(store));
 
  g_object_unref(store);
}
 
void add_to_list(GtkWidget *list, const gchar *str)
{
 
  GtkListStore *store;
  GtkTreeIter iter;
 
  store = GTK_LIST_STORE(gtk_tree_view_get_model
              (GTK_TREE_VIEW(list)));
 
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, LIST_ITEM, str, -1);
}
 
 
void on_changed(GtkWidget *widget, gpointer label)
{
 
  GtkTreeIter iter;
  GtkTreeModel *model;
  gchar *value;
 
  if (gtk_tree_selection_get_selected(
        GTK_TREE_SELECTION(widget), &model, &iter))
  {
 
    gtk_tree_model_get(model, &iter, LIST_ITEM, &value, -1);
    gtk_label_set_text(GTK_LABEL(label), value);
    g_free(value);
  }
}
 
int main(int argc, char *argv[])
{
 
  GtkWidget *window;
  GtkWidget *list;
 
  GtkWidget *vbox;
  GtkWidget *label;
  GtkTreeSelection *selection;
 
  gtk_init(&argc, &argv);
 
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  list = gtk_tree_view_new();
 
  gtk_window_set_title(GTK_WINDOW(window), "List view");
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);//设置为居中。
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);
  gtk_widget_set_size_request(window, 270, 250);
 
  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
 
  vbox = gtk_vbox_new(FALSE, 0);
 
  gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 5);
 
  label = gtk_label_new("");
  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
 
  gtk_container_add(GTK_CONTAINER(window), vbox);
 
  init_list(list);
  add_to_list(list, "Aliens");
  add_to_list(list, "Leon");
  add_to_list(list, "The Verdict");
  add_to_list(list, "North Face");
  add_to_list(list, "Der Untergang");
 
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
 
  g_signal_connect(selection, "changed",
           G_CALLBACK(on_changed), label);
 
  g_signal_connect(G_OBJECT (window), "destroy",
           G_CALLBACK(gtk_main_quit), NULL);
 
  gtk_widget_show_all(window);
 
  gtk_main();
 
  return 0;
}

在我们上面的这个示例代码中,我们将向大家展示的是5个条目并布置于GtkTreeView 构件中。我们首先在window中放置一个GtkVBox 构件。 在这个 GtkVBox 构件中含有两个构件:GtkTreeView和GtkLabel。

list = gtk_tree_view_new();
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);

调用list()函数,初始化构件list。

1
2
3
4
renderer = gtk_cell_renderer_text_new();
 column = gtk_tree_view_column_new_with_attributes("List Items",
     renderer, "text", LIST_ITEM, NULL);
 gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);

在初始化函数中,我们生成了只有一栏的GtkTreeView。

1
2
3
store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING);
 gtk_tree_view_set_model(GTK_TREE_VIEW(list),
   GTK_TREE_MODEL(store));

接下来我们又生成了一个GtkListStore 构件(a model) 然后把它与list 构件绑定。

g_object_unref(store);

这个 model 被自动的销毁,以释放内存空间。

add_to_list(list, "Aliens");

上面就是在调用add_to_list()函数,实现向list 中在增加一个选项的功能。

store = GTK_LIST_STORE(gtk_tree_view_get_model
(GTK_TREE_VIEW(list)));

gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, LIST_ITEM, str, -1);

在函数add_to_list() 中,我们利用系统函数gtk_tree_view_get_model()来获得model。我们生成新的一行并把行中的数据交给model处理,这里正是借助GtkTreeIter来完成这个功能。

selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));

GtkTreeSelection际上并不需要明确生成。在这里,我们是利用 GtkTreeView构件自动来生成。来帮助完成这项工作的正如你所见到的是系统函数gtk_tree_view_get_selection()。

好了再练习一下

增加一栏

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <gtk/gtk.h>
 
enum
{
  LIST_ITEM = 0,
  LIST_AGE,
  N_COLUMNS
};
 
 
void init_list(GtkWidget *list)
{
  //要想让视图显示出数据,必须建立GtkCellRenderer与GtkTreeViewColumn
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;
  GtkListStore *store;
   
  //建立一个GtkCellRenderer
  renderer = gtk_cell_renderer_text_new (); 
  //建立一个带标题的列 并且将renderer放入其中使其能显示内容
  column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", LIST_ITEM, NULL); 
  //将列加入gtk_tree_view
  gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
   
   
  //建立一个GtkCellRenderer
  renderer = gtk_cell_renderer_text_new (); 
  //g_object_set (G_OBJECT (renderer), "xalign", 1.0, NULL);//居右
  //建立一个带标题的列 并且将renderer放入其中使其能显示内容
  column = gtk_tree_view_column_new_with_attributes("List age", renderer, "text", LIST_AGE, NULL); 
  //将列加入gtk_tree_view
  gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
   
   
 
  store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING,G_TYPE_INT);
   
   
  //关联视图与模型
  gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store));
 
  //将数据模型交给视图管理,视图销毁时数据会被一同销毁
  g_object_unref(store);
}
 
void add_to_list(GtkWidget *list, const gchar *str ,gint age)
{
 
  GtkListStore *store;
  GtkTreeIter iter;
 
  store = GTK_LIST_STORE(gtk_tree_view_get_model
              (GTK_TREE_VIEW(list)));
 
  gtk_list_store_append(store, &iter);
  gtk_list_store_set(store, &iter, LIST_ITEM, str,LIST_AGE,age, -1);
}
 
 
 
void on_changed(GtkWidget *widget, gpointer label)
{
 
  GtkTreeIter iter;
  GtkTreeModel *model;
  gchar *value;
   
  //获得treeview中选中的一行的GtkTreeIter
  if (gtk_tree_selection_get_selected( GTK_TREE_SELECTION(widget), &model, &iter))
  {
 
    gtk_tree_model_get(model, &iter, LIST_ITEM, &value, -1);
    gtk_label_set_text(GTK_LABEL(label), value);
    g_free(value);
  }
}
 
int main(int argc, char *argv[])
{
 
  GtkWidget *window;
  GtkWidget *list;
 
  GtkWidget *vbox;
  GtkWidget *label;
  GtkTreeSelection *selection;
 
  gtk_init(&argc, &argv);
 
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  list = gtk_tree_view_new();
 
  gtk_window_set_title(GTK_WINDOW(window), "List view");
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_container_set_border_width(GTK_CONTAINER(window), 10);
  gtk_widget_set_size_request(window, 270, 250);
 
  //设置标题的可见性状态。
  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE );
 
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);//gtk_vbox_new(FALSE, 0);
 
  gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 5);
 
  label = gtk_label_new("");
  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
 
  gtk_container_add(GTK_CONTAINER(window), vbox);
 
  init_list(list);
  add_to_list(list, "Aliens"    ,10 );
  add_to_list(list, "Leon"     ,2 );
  add_to_list(list, "The Verdict" ,30 );
  add_to_list(list, "North Face"  ,4 );
  add_to_list(list, "Der Untergang",50 );
 
   
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
 
  g_signal_connect(selection, "changed",
           G_CALLBACK(on_changed), label);
 
  g_signal_connect(G_OBJECT (window), "destroy",
           G_CALLBACK(gtk_main_quit), NULL);
 
  gtk_widget_show_all(window);
 
  gtk_main();
 
  return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助


文章分类
前端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐