王朝网络
分享
 
 
 

Linux GUI编程笔记之GTK+篇(2)

王朝system·作者佚名  2006-01-09
宽屏版  字体: |||超大  

Linux GUI编程笔记之GTK+篇(2)

-----窗体布局

从上文我们知道了GTK+程序的基本框架和其内在的工作原理,现在让我们一起来学习如何在一个窗体上摆放控件。用惯了Windows下VB,Delphi等RAD工具的朋友一定会感到疑惑,怎么在窗体上摆一个控件还要大动干戈?这可能是Linux编程的缺陷吧(虽然我们也可以用glade等工具进行GUI构建,但是和VB等傻瓜工具比还是很有差距的)。但是我还是喜欢自己用代码实现GUI,虽然虽然好像有点自讨苦吃,但是这样却使我有一种真正在编程的感觉:)

要了解怎么样在GTK+窗体上摆放控件,我们首先需要了解“窗体布局”这个概念。不知道现在C#等.NET平台语言有没有“窗体布局器”这个概念(我以前用VB6.0, VC6.0的时候是没有的,不过Java里面有Layout这个类实现窗体布局),对于用惯Windows下开发工具的朋友肯定对这个概念比较陌生。在GTK+里不能像VB那样直接把所有需要的控件都直接加到窗体上,我们需要用各种容器(box,table等)的组合来完成这些动作。各种能够容纳其他控件的特殊控件(容器)都是窗体布局器。

在GTK+中有两种常用的布局容器:盒状容器(box)和表格容器(table)

下面让我们来分别认识他们:

1 - 盒状容器

盒状容器是能够线性容纳子控件的容器,分为水平盒(gtk_hbox)和垂直盒(gtk_vbox)两种。

水平盒就是能够使子控件水平一线排开的容器,垂直盒则让子控件从上到下垂直排列。

以水平盒为例子,产生一个水平盒的函数是:

GtkWidget *gtk_hbox_new ( gboolean homogeneous, //子控件是否一样大小(和最大的控件相同)

gint spacing ); //默认子控件之间的间距

在盒子里加入子控件的函数:

void gtk_box_pack_start( GtkBox *box, //盒子

GtkWidget *child, //子控件

gboolean expand, //盒子是否占据所有分配的空间

gboolean fill, //子控件是否分开(TRUE为分开)或挤在一起

guint padding ); //子控件是否丰满(TRUE且expand应该为TRUE)或者缩成一定大小

为了理解这两个程序,我们看一个完整的程序:

#include

/* 回调函数,使程序退出 */

void quit_program(GtkWidget *widget, gpointer data)

{

gtk_main_quit();

}

int main(int argc, char *argv[])

{

GtkWidget *window;

GtkWidget *box;

GtkWidget *button;

gtk_init(&argc, &argv); /* 初始化程序 */

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window), "横向盒状容器");

g_signal_connect(G_OBJECT(window), "destroy",

G_CALLBACK(quit_program), NULL);

gtk_container_set_border_width(GTK_CONTAINER(window), 5);

box = gtk_hbox_new (FALSE, 0); /* 新建一个横向盒子,子控件不需要一样大,默认间距0 */

/* 建立4个按钮 */

button = gtk_button_new_with_label ("按钮一");

gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);

gtk_widget_show (button);

button = gtk_button_new_with_label ("按钮二");

gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);

gtk_widget_show (button);

button = gtk_button_new_with_label ("按钮三");

/* 使这个按钮占据多余空间 */

gtk_box_pack_start (GTK_BOX (box), button, TRUE, TRUE, 3);

gtk_widget_show (button);

button = gtk_button_new_with_label ("按钮四");

gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 3);

gtk_widget_show (button);

gtk_container_add(GTK_CONTAINER(window), box);

gtk_widget_show(box);

gtk_widget_show(window);

gtk_main();

return 0;

}

这个程序编译运行后的结果如下:

按钮3因为设置了expand=TRUE,fill=TRUE,于是充分扩展了自己; 其他按钮都缩在最小的范围内。

同样,垂直盒子也有同样的函数:

GtkWidget* gtk_vbox_new(gboolean homogeneous, //子控件是否同样大小

gint spacing); //默认的子控件之间间距

void gtk_box_pack_start( GtkBox *box, //盒子

GtkWidget *child, //子控件

gboolean expand, //盒子是否占据所有分配的空间

gboolean fill, //子控件是否分开(TRUE为分开)或挤在一起

guint padding ); //子控件是否丰满(TRUE且expand应该为TRUE)或者缩成一定大小

2 - 表格容器

表格容器是在水平和垂直方向都可以摆放多个子控件的容器,想象一个表格容器就像一个Excel表格一样,子控件可以占据一个格子,也可以占据连续的多个格子,这样就可以十分自由的排列我们的子控件了。

产生一个新表格容器的函数是:

GtkWidget *gtk_table_new( guint rows, //行数

guint columns, //列数

gboolean homogeneous ); //子控件是否一样大(和最大子控件一样大)

假设我们用: gtk_table_new(2, 2, TRUE)生成一个表格,其逻辑上就像下面的图形一样:

0 1 2

0+----------+----------+

| | |

1+----------+----------+

| | |

2+----------+----------+

然后我们可以用下面的函数往表格上面填加子控件:

void gtk_table_attach( GtkTable *table, //盒子

GtkWidget *child, //要加入盒子的子控件

guint left_attach, //左边界

guint right_attach, //右边界

guint top_attach, //上边界

guint bottom_attach, //下边界

GtkAttachOptions xoptions,

GtkAttachOptions yoptions,

guint xpadding,

guint ypadding );

哇!那么多参数,让人怎么怎么用啊?!

呵呵,不要害怕:)其实很简单的,4个XXX_attach()是控制子控件摆放位置的:

如果我们要在左上角那个格子放一个控件,那么left_attach=0, right_attach=1,

top_attach=0, bottom_attach=1(好象用4条线隔了一个空间)

同理,如果想在下面一整行摆一个控件,那么left_attach=0, right_attach=2,

top_attach=1, bottom_attach=2

然后下面两个参数xoption, yoption是控制子控件行为的,控制参数有:

GTK_FILL: 如果盒子比子控件大,而且GTK_FILL已经设置,则子控件会扩展成盒子那么大

GTK_SHRINK:如果GTK_SHRINK已经设置,那么当用户改变窗口大小时(变小),子控件会跟着变小

GTK_EXPAND:如果这个位设置了,那么盒子容器就会占据所有窗体上留下的空间

使用的时候我们可以用或”|“符号连接他们一起使用,比如:GTK_FILL | GTK_EXPAND

再下面两个参数就是代表子控件在X(横向), Y(竖向)方向上的间距。

怎么样,这个函数也不是挺简单的?不过要是你觉得这个函数还是太麻烦,你还可以使用下面这个函数:

void gtk_table_attach_defaults( GtkTable *table, //盒子

GtkWidget *widget, //要加入盒子的子控件

guint left_attach,

guint right_attach,

guint top_attach,

guint bottom_attach );

这个函数省略了后面4个参数,它默认xoption, yoption都是:GTK_FILL | GTK_EXPAND

然后xpadding, ypadding都是0, 这样一来节省了我们不少时间。

我们学完了GTK+的布局容器,现在可以用各种控件来组合我们的应用程序界面了。各种容器之间又可以相互嵌套,这样一来构造复杂的界面也变得容易了。但是GTK+中也提供了一种让我们像Windows窗体那样直接就可以往窗体上摆控件的方法,那就是用GtkFixed:

GtkWidget* gtk_fixed_new(void); /* 建立一个自由布局控件 */

/* 往布局上加子控件 */

void gtk_fixed_put(GtkFixed *fixed, //自由布局控件

GtkWidget *widget, //要加入的子控件

gint x, //相对于fixed左上角的横坐标

gint y); //相对于fixed左上角的纵坐标

/* 移动子控件 */

void gtk_fixed_move(GtkFixed *fixed, //自由布局控件

GtkWidget *widget, //要加入的子控件

gint x, //新的X坐标

gint y); //新的Y坐标

有了以上几个函数,我们就可以像Windows Form一样操作控件了,比如以下代码:

fixed = gtk_fixed_new();

gtk_widget_set_usize(fixed,150,150);

button1 = gtk_button_new_with_label("按钮一");

gtk_fixed_put(GTK_FIXED(fixed),button1,5,5);

button2 = gtk_button_new_with_label("按钮二");

gtk_fixed_put(GTK_FIXED(fixed),button2,55,55);

button3 = gtk_button_new_with_label("按钮三");

gtk_fixed_put(GTK_FIXED(fixed),button3,105,105);

会产生如下的界面:

好了,关于GTK+的窗体布局部分,我们已经学习完了。

PS: 本文参照了IBM DeveloperWorks里面宋国伟先生的一篇文章,且借用了几张图片,在这里表示感谢。

原文请查看:http://www-900.ibm.com/developerWorks/cn/linux/l-gtk/index.shtml

-----------2004-7-29

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有