这次网络管理工具的编写主要使用GTK作为画图工具;在这里回顾一下其中用到的tree_view构件
GtkTreeView 构件是一个高级的构件,利用他可以制作出漂亮的普通列表或者是树状的列表;这个构件里可以包含一或者多行
在GtktreeView构件中还有着其他几个独立的对象结构(objects)。其中 GtkCellRenderer 决定了在GtkTreeViewColumn中的数据究竟是如何来进行显示呈现的。GtkListStore 和 GtkTreeStore 的功能为体现模型(model)的作用。也就是说他们是用来处理和分析将要在GtkTreeView显示的数据的。 GtkTreeIter 则是一个数据结构被用于在GtkTreeView构件中,对行中的数据进行操作。 GtkTreeSelection 则是用来处理选项的。
下边是我这次项目中所写的的部分关于tree_view的代码:
GtkTreeView 构件是一个高级的构件,利用他可以制作出漂亮的普通列表或者是树状的列表;这个构件里可以包含一或者多行
在GtktreeView构件中还有着其他几个独立的对象结构(objects)。其中 GtkCellRenderer 决定了在GtkTreeViewColumn中的数据究竟是如何来进行显示呈现的。GtkListStore 和 GtkTreeStore 的功能为体现模型(model)的作用。也就是说他们是用来处理和分析将要在GtkTreeView显示的数据的。 GtkTreeIter 则是一个数据结构被用于在GtkTreeView构件中,对行中的数据进行操作。 GtkTreeSelection 则是用来处理选项的。
下边是我这次项目中所写的的部分关于tree_view的代码:
struct process * curproc ; //一个存放数据的结构体
static int net_flow_add_status(NTApplet *applet)
{
curproc=processes;
gtk_list_store_clear(applet->list_store); //清空list_store
while(curproc != NULL)
{
if(curproc->pid != -1 )
{
gtk_list_store_append(applet->list_store,&applet->tree_iter); //添加一行list_store;applet->tree_iter,GtkTreeIter 则是一个数据结构被用于在GtkTreeView构件中,对行中的数据进行操作
gtk_list_store_set (applet->list_store, &applet->tree_iter, 0, "gtk-cdrom", 1, curproc->name,2,curproc->pid,3,uid2username(curproc->uid), 4,format_show(0,curproc->sent_sec),5,format_show(0,curproc->rcvd_sec),-1, 6,format_show(1,curproc->rcvd_total),7,format_show(1,curproc->sent_total));//设置数据
}
curproc = curproc->next;
}
return TRUE;
}
static void net_flow_update_status(NTApplet *applet)
{
g_timeout_add (1000, (GSourceFunc)net_flow_add_status,applet); //定时器,每过一秒更新一次数据
}
static void net_state_init (NTApplet *applet)
{
GtkWidget *sw;
GtkWidget *tree_view; //treeview 控件
GtkTreeViewColumn *column; //一个tree_view 包含多个列
GtkCellRenderer *cell_renderer; //一个column 可以有多个数据组合方式
GtkTreeSelection *selection;
if(applet->net_flow_update_flag) //此程序只需要初始化一次;
{
gtk_widget_show_all(applet->vbox_state);
return;
}
applet->vbox_state = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
sw = gtk_scrolled_window_new(NULL, NULL); //创建窗口滚动条构件
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);//设置滚动条出现的方式
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN); //
applet->list_store = gtk_list_store_new(8, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,G_TYPE_STRING); //new一个list_store并设置list_store属性(个人觉着这个是对tree_view中有几列数据的初始化)
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (applet->list_store));//创建tree_view模型;
gtk_box_pack_start (GTK_BOX (applet->vbox_current), applet->vbox_state, TRUE, TRUE, 0);
gtk_widget_show(applet->vbox_state);
gtk_box_pack_start (GTK_BOX (applet->vbox_state), sw, TRUE, TRUE, 0);
gtk_widget_show(sw);
gtk_container_add (GTK_CONTAINER(sw), tree_view);
gtk_widget_show(tree_view);
//第一列
column = gtk_tree_view_column_new(); //初始化第一列
gtk_tree_view_column_set_title(column,"应用程序");
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, 70);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view),column); //摆放到tree_view上
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);//设置数据属性
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,NULL);
//第二列
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_title (column, "进程ID");
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, 70);
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", 2, NULL);
//第三列
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title (column, "用户名");
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, 70);
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, "下载速度");
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, 70);
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);
//第五列
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title (column, "上传速度");
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, 70);
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", 5,
NULL);
//第六列
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title (column, "已下载流量");
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_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", 6,
NULL);
//第七列
column = gtk_tree_view_column_new();
gtk_tree_view_column_set_title (column, "已上传流量");
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", 7,
g_thread_new("updatedata",(GThreadFunc)net_flow_update_status, applet);//创建一个线程用于实时更新数据
applet->net_flow_update_flag=1;//标志位,使得此tree_view只初始化一次
gtk_widget_show_all(applet->vbox_state);
}
applet为我们所定义的一个结构体指针,考虑到list_store里数据需要在后台实时更新,所以采用开辟线程的方式;