Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57949
  • 博文数量: 19
  • 博客积分: 226
  • 博客等级: 二等列兵
  • 技术积分: 110
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-02 18:33
文章分类

全部博文(19)

文章存档

2011年(19)

分类: 嵌入式

2011-12-16 21:38:36

GTKtreeview的学习

       其实接触gtk也没多久,只是把学到的做一总结,也算是备忘吧,以后真要忘了的话【几乎是铁定的了】,翻着看看,还能想起来。

       感觉treeview控件对于gtk的入门来说应该算比较高级的构件了,而且学习它的同时也可以学习下gtk+是如何实现MVC架构的。

       说起MVC,现在应该还算比较流行的了。其实也就是model-view-controller,就其本身而言,其实好像也没多大新意。Gtk+对其的实现不是很标准,但应该说有些东西还是套用的,因为本身差别并不大。

       treeview的使用为例,

       首先我们定义model

GtkTreeModel  *list_model_create()
{  
  GtkListStore 
*store;
  store 
= gtk_list_store_new(3,G_TYPE_STRING, G_TYPE_STRING,G_TYPE_STRING);
  
return GTK_TREE_MODEL(store);
}

 

 当然这里面先不加载具体的数据。Gtk中用于treeviewmodel一般可以用liststoretreestore来实现。

 然后,将viewmodel关联起来

 


void list_view_ini(GtkWidget *list)
{
  GtkCellRenderer 
*renderer_icon,*renderer_text;
  GtkTreeViewColumn 
*column;
  renderer_icon 
= gtk_cell_renderer_pixbuf_new();
  renderer_text 
= gtk_cell_renderer_text_new();
  column
=gtk_tree_view_column_new ();
  gtk_tree_view_column_set_title(column,
"hello world");  
  gtk_tree_view_column_pack_start(column,renderer_icon,FALSE);
  gtk_tree_view_column_pack_start(column,renderer_text,FALSE);  gtk_tree_view_column_add_attribute(column,renderer_icon,
"stock-id",0); gtk_tree_view_column_add_attribute(column,renderer_text,"text",1);
gtk_tree_view_column_add_attribute(column,renderer_text,
"foreground",2);
  gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
}
 

看起来比较复杂,其实还是比较简单的

首先view要通过column来展现,而column中的内容,则有store来提供,当然store并不管里面具体是什么东西,所以,就需要cellrenderer来描述。而具体的数据可能又有很多行(row),每一行怎么区别呢,就要用到iter

当然上面的实现还是复杂了些,因为每个列有两个cellrenderer(一个用来描述图标,另一个用来描述文字),如果每一个列(column)只有一种属性,或是文本,或是图片,那就可以用更方便的使用如下函数。

column = gtk_tree_view_column_new_with_attributes("column 1",renderer_icon, "stock-id"0, NULL);
gtk_list_view_append_column(GTK_TREE_VIEW(list), column);

这样就简单多了。

至此我们就建立了modelview,当然具体的数据还没有添加。

在添加具体数据之前,先看看在main函数中应如何调用

GtkWidget *list;
list
= gtk_tree_view_new_with_model(list_model_create());
list_view_ini(list);

 

下面要往里面填数据了,

 


void list_append(GtkWidget *list, const gchar *icon,const gchar *str,const gchar *col)
{
  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, 0,icon,1, str,2,col, -1);
}

 

我们定义了一个插入用的函数,传入的后三个参数iconstrcol分别表示图标,文自信息和文字信息对应的颜色,图标对应的cellrendererpixbuf型的,而文字信息及其颜色是一个textcellrenderer的两个属性,前面通过pack打包到一个column里面了。

main函数中,只需简单的插入数据就行了,例如

list_append(list,GTK_STOCK_CLOSE,"hello","grey");
list_append(list,GTK_STOCK_CLOSE,
"world","grey");


treeview已经构建完成了,但这似乎没有什么用啊,要真正有用还需要知道如何获取选择信息,

当然首先要做一信号的链接
model=gtk_tree_view_get_model(GTK_TREE_VIEW(list));
g_signal_connect(selection, 
"changed", G_CALLBACK(on_changed), model);

这里将model传入是为了实现一个简单的图标变化。当然还需额外说明的是菜单的选择还需要使用到一个名为selection的构件,它是专门用来描述treeview的选择项的
GtkTreeSelection *selection; 
selection 
= gtk_tree_view_get_selection(GTK_TREE_VIEW(list));

选择项若有所改变其相应的回调函式如下,
void  on_changed(GtkWidget *widget,  GtkTreeModel *model) 
{
  GtkTreeIter iter;
 
  
char *value;
  gtk_tree_model_get_iter_from_string (model, 
&iter, "0");
      
if(gtk_tree_selection_iter_is_selected(GTK_TREE_SELECTION(widget),&iter))
      {
          gtk_list_store_set(GTK_LIST_STORE(model),
&iter,LIST_ICON,GTK_STOCK_APPLY,LIST_COLOR,"green",-1);
gtk_tree_model_get_iter_from_string (model, 
&iter, "1");
gtk_list_store_set(GTK_LIST_STORE(model),
&iter,LIST_ICON,GTK_STOCK_CLOSE,LIST_COLOR,"red",-1);
          
      }
      
else
      {
          gtk_list_store_set(GTK_LIST_STORE(model),
&iter,LIST_ICON,GTK_STOCK_CLOSE,LIST_COLOR,"red",-1);
gtk_tree_model_get_iter_from_string (model, 
&iter, "1");    gtk_list_store_set(GTK_LIST_STORE(model),&iter,LIST_ICON,GTK_STOCK_APPLY,LIST_COLOR,"green",-1);
          
      }
}
这里面的方法还是比较麻烦的逐一判断的那种,这主要是为了能够实现对图标的选择性修改,当然一般来说如果只需要获取选择信息可以用一种很简单的方式。

 


void  on_changed(GtkWidget *widget, gpointer data) 
{
  GtkTreeIter iter;
  GtkTreeModel 
*model;
  
char *value;
  
if (gtk_tree_selection_get_selected(
      GTK_TREE_SELECTION(widget), 
&model, &iter))
 {
    gtk_tree_model_get(model, 
&iter, LIST_ITEM, &value,  -1);
    g_free(value);
  }
}


 

这里要注意获取的value实则指向了一块新分配在自由存储区的内存,用完要及时释放掉。

 

至此,就完成了的一个简单的treeview小程序。

下面贴出完整的代码,


  1 #include <gtk/gtk.h>
  2 
  3 enum
  4 {
  5     LIST_ICON=0,
  6     LIST_TEXT ,
  7     LIST_COLOR,
  8     N_COLUMNS
  9 };
 10 
 11 GtkTreeModel  *list_model_create()
 12 {  
 13 
 14     GtkListStore *store;
 15     store = gtk_list_store_new(N_COLUMNS,G_TYPE_STRING, G_TYPE_STRING,G_TYPE_STRING);
 16     return GTK_TREE_MODEL(store);
 17 }
 18 void list_view_ini(GtkWidget *list)
 19 {
 20     GtkCellRenderer *renderer_icon,*renderer_text;
 21     GtkTreeViewColumn *column;
 22     renderer_icon = gtk_cell_renderer_pixbuf_new();
 23     renderer_text = gtk_cell_renderer_text_new();
 24 
 25     column=gtk_tree_view_column_new ();
 26     gtk_tree_view_column_set_title(column,"hello world");  
 27     gtk_tree_view_column_pack_start(column,renderer_icon,FALSE);
 28     gtk_tree_view_column_pack_start(column,renderer_text,FALSE);
 29     gtk_tree_view_column_add_attribute(column,renderer_icon,"stock-id",LIST_ICON);
 30     gtk_tree_view_column_add_attribute(column,renderer_text,"text",LIST_TEXT);
 31     gtk_tree_view_column_add_attribute(column,renderer_text,"foreground",LIST_COLOR);
 32     gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
 33 }
 34 void list_append(GtkWidget *list, const gchar *icon,const gchar *str,const gchar *col)
 35 {
 36     GtkListStore *store;
 37     GtkTreeIter iter;
 38 
 39     store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
 40 
 41     gtk_list_store_append(store, &iter);
 42     gtk_list_store_set(store, &iter, LIST_ICON,icon,LIST_TEXT, str,LIST_COLOR,col, -1);
 43 
 44 }
 45 
 46 void  on_changed(GtkWidget *widget,  GtkTreeModel *model) 
 47 {
 48     GtkTreeIter iter;
 49 
 50     char *value;
 51 
 52     gtk_tree_model_get_iter_from_string (model, &iter, "0");
 53     if (gtk_tree_selection_iter_is_selected(GTK_TREE_SELECTION(widget),&iter))
 54     {
 55         gtk_list_store_set(GTK_LIST_STORE(model),&iter,LIST_ICON,GTK_STOCK_APPLY,LIST_COLOR,"green",-1);
 56         gtk_tree_model_get_iter_from_string (model, &iter, "1");
 57         gtk_list_store_set(GTK_LIST_STORE(model),&iter,LIST_ICON,GTK_STOCK_CLOSE,LIST_COLOR,"red",-1);
 58 
 59     }
 60     else
 61     {
 62         gtk_list_store_set(GTK_LIST_STORE(model),&iter,LIST_ICON,GTK_STOCK_CLOSE,LIST_COLOR,"red",-1);
 63         gtk_tree_model_get_iter_from_string (model, &iter, "1");
 64         gtk_list_store_set(GTK_LIST_STORE(model),&iter,LIST_ICON,GTK_STOCK_APPLY,LIST_COLOR,"green",-1);
 65 
 66     }
 67 
 68 }
 69 int main (int argc, char *argv[])
 70 {
 71     GtkWidget *window;
 72 
 73     GtkWidget *list;
 74     GtkWidget *vbox;
 75     GtkTreeModel *model;
 76     GtkTreeSelection *selection; 
 77     gtk_init(&argc, &argv);
 78 
 79     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 80     gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
 81     gtk_container_set_border_width(GTK_CONTAINER(window), 10);
 82     gtk_widget_set_size_request(window, 270250);
 83     gtk_window_set_title(GTK_WINDOW(window), "list View");
 84 
 85 
 86     vbox = gtk_vbox_new(FALSE, 0);
 87     list= gtk_tree_view_new_with_model(list_model_create());
 88 
 89     gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 5);
 90     gtk_container_add(GTK_CONTAINER(window), vbox);
 91 
 92     list_view_ini(list);
 93     list_append(list,GTK_STOCK_CLOSE,"hello","grey");
 94     list_append(list,GTK_STOCK_CLOSE,"world","grey");
 95 
 96     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
 97     gtk_tree_selection_set_mode(selection,GTK_SELECTION_SINGLE);
 98     model=gtk_tree_view_get_model(GTK_TREE_VIEW(list));
 99     g_signal_connect(selection, "changed", G_CALLBACK(on_changed), model);
100     g_signal_connect(G_OBJECT (window), "destroy",G_CALLBACK(gtk_main_quit), NULL);
101     gtk_widget_show_all(window);
102     gtk_main ();
103     return 0;
104 }

阅读(1741) | 评论(0) | 转发(0) |
0

上一篇:GtkComboBox 與 GtkListStore

下一篇:TreeView

给主人留下些什么吧!~~