### 构件概述
在GTK中创建一个构件的一般步骤:
1、gtk_*_new():创建各种构件的函数
2、把所有相连接的信号都连接到对应的信号处理函数
3、设定构件的属性
4、用gtk_container_add() or grk_box_pack_start()等适当的函数把构件放置到一个控件中,
5、gtk_widget_show()显示构件。
### 组装构件
多 数组装是通过创建一些“盒(boxes)”来达成的,这是些不可见的构件容器,它们有两种形式:一种是横向盒(horizontal box),一种是纵向盒(vertical box)。当我们组装构件到横向盒里时,这些构件就依着我们调用的顺序由左至右或从右到左水平地插入进去。在纵向盒里,则从顶部到底部或相反地组装构件, 你可以使用任意的盒组合,比如盒套盒或者盒挨着盒,用以产生你想要的效果。
要创建一个新的横向盒我们调用 gtk_hbox_new(),对于纵向盒,用 gtk_vbox_new()。gtk_box_pack_start() 和 gtk_box_pack_end() 函数用来将对象组装到这些容器中。gtk_box_pack_start() 将对象从上到下组装到纵向盒中,或者从左到右组装到横向盒中。gtk_box_pack_end() 则相反,从下到上组装到纵向盒中,或者从右到左组装到横向盒中。使用这些函数允许我们调整自己的构件向左或向右对齐,同时也可以混入一些其它的方法来达到 我们想要的设计效果。在我们的示例中多数使用gtk_box_pack_start()。被组装的对象可以是另一个容器或构件。事实上,许多构件本身就是容器,包括按钮,只不过我们通常在按钮中只放 入一个标签。看下面的具体例子:
~~~
/*File:packbox.c
*Date:2013-11-17
*Author:sjin
*Mail:413977243@qq.com
*/
#include <stdio.h>
#include <gtk/gtk.h>
#include <stdlib.h>
gint delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{
gtk_main_quit();
return FALSE;
}
/*生成一个填满按钮-标签的横向盒,我们将感兴趣的参数传递进这个函数
* 我们不显示这个盒子,但显示它内部的所有东西
*/
GtkWidget * make_box(gboolean homogeneous,gint spacing,gboolean expand,gboolean fill,guint padding)
{
GtkWidget *box;
GtkWidget *button;
char padstr[80];
/*homogeneous:确定所有控件的大小
* TRUE:表示组装和计算最大控件的大小,然后其他控件按照最大控件的大小分配
* FALSE:建立不同大小的控件,以各自内容。
* spacing:用它来确定插入组装和的构件之间的空间。
* 0:表示空间之间不留空间
* */
box = gtk_hbox_new (homogeneous,spacing);
button = gtk_button_new_with_label("gtk_box_pack");
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
button = gtk_button_new_with_label("box,");
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
button = gtk_button_new_with_label("button");
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
if(expand == TRUE){
button = gtk_button_new_with_label("TRUE,");
} else {
button = gtk_button_new_with_label("FALSE,");
}
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
button = gtk_button_new_with_label(fill?"TRUE":"FALSE");
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
sprintf(padstr,"%d);",padding);
button = gtk_button_new_with_label(padstr);
gtk_box_pack_start(GTK_BOX(box),button,expand,fill,padding);
gtk_widget_show(button);
return box;
}
int main(int argc,char *argv[])
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *separator;
GtkWidget *label;
GtkWidget *quitbox;
int which;
/*初始化*/
gtk_init(&argc,&argv);
if(argc != 2){
fprintf(stderr,"usage:packbox num ,where num is 1,2,3\n");
exit(1);
}
which = atoi(argv[1]);
/*创建窗口*/
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/*这个一般必要有delete_event信号到主窗口*/
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);
/*设置窗口宽度*/
gtk_container_set_border_width(GTK_CONTAINER(window),80);
/*设置窗口标题*/
gtk_window_set_title(GTK_WINDOW(window),"组装盒练习");
/* 我们创建一个纵向盒(vbox)把横向和组装进来
*这样我们可以将填满按钮的很想和一个个的堆叠到这个纵向盒子里
*/
box1 = gtk_vbox_new(FALSE,0);
/**/
switch(which){
case 1:
/*创建一个标签*/
label = gtk_label_new("gtk_hbox_new(FALSE,0);");
/*使标签靠左排列*/
gtk_misc_set_alignment(GTK_MISC(label),0,0);
/*将标签组装到纵向盒中*/
gtk_box_pack_start(GTK_BOX(box1),label,FALSE,FALSE,0);
/*显示标签*/
gtk_widget_show(label);
/*调用我们生成盒的函数-homogeneous = FALSE,spacing = 0
* * expand = FALSE,fill = FALSE,padding = 0 */
box2 = make_box(TRUE,0,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*调用我们生成盒的函数-homogeneous = FALSE,spacing = 0
* * expand = TRUE,fill = FALSE,padding = 0 */
box2 = make_box(FALSE,0,TRUE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*调用我们生成盒的函数-homogeneous = FALSE,spacing = 0
* * expand = TRUE,fill = TRUE,padding = 0 */
box2 = make_box(FALSE,0,TRUE,TRUE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*创建一个分割线,并组装到纵向盒*/
separator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,5);
gtk_widget_show(separator);
/*创建一个新的标签,并显示它*/
label = gtk_label_new("gtk_hbox_new(TRUE,0);");
gtk_misc_set_alignment(GTK_MISC(label),0,0);
gtk_box_pack_start(GTK_BOX(box1),label,FALSE,FALSE,0);
gtk_widget_show(label);
box2 = make_box(TRUE,0,TRUE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
box2 = make_box(FALSE,0,TRUE,TRUE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*创建一个分割线,并组装到纵向盒*/
separator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,5);
gtk_widget_show(separator);
break;
case 2:
/*创建一个新的标签,并显示它*/
label = gtk_label_new("gtk_hbox_new(FALSE,10);");
gtk_misc_set_alignment(GTK_MISC(label),0,0);
gtk_box_pack_start(GTK_BOX(box1),label,FALSE,FALSE,0);
gtk_widget_show(label);
box2 = make_box(FALSE,10,TRUE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
box2 = make_box(FALSE,10,TRUE,TRUE,0);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*创建一个分割线,并组装到纵向盒*/
separator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,5);
gtk_widget_show(separator);
/*创建一个新的标签,并显示它*/
label = gtk_label_new("gtk_hbox_new(FALSE,0);");
gtk_misc_set_alignment(GTK_MISC(label),0,0);
gtk_box_pack_start(GTK_BOX(box1),label,FALSE,FALSE,0);
gtk_widget_show(label);
box2 = make_box(FALSE,0,TRUE,FALSE,10);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
box2 = make_box(FALSE,0,TRUE,TRUE,10);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*创建一个分割线,并组装到纵向盒*/
separator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,5);
gtk_widget_show(separator);
break;
case 3:
/*示范gtk_box_pack_end()右对齐构件的能力*/
box2 = make_box(FALSE,0,FALSE,FALSE,0);
/*创建放在末端的标签*/
label = gtk_label_new("end");
gtk_box_pack_end(GTK_BOX(box2),label,FALSE,FALSE,0);
gtk_widget_show(label);
gtk_box_pack_start(GTK_BOX(box1),box2,FALSE,FALSE,0);
gtk_widget_show(box2);
/*放在底部的分割线*/
separator = gtk_hseparator_new();
gtk_widget_set_size_request(separator,400,5);
gtk_box_pack_start(GTK_BOX(box1),separator,FALSE,TRUE,5);
gtk_widget_show(separator);
break;
default:
break;
}
/*创建一个新的横向盒,用来推出按钮*/
quitbox = gtk_hbox_new(FALSE,0);
button = gtk_button_new_with_label("退出");
g_signal_connect_swapped(G_OBJECT(button),"clicked",G_CALLBACK(delete_event),window);
gtk_box_pack_start(GTK_BOX(quitbox),button,TRUE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box1),quitbox,TRUE,FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box1);
gtk_widget_show(button);
gtk_widget_show(quitbox);
gtk_widget_show(box1);
gtk_widget_show(window);
gtk_main();
return 0;
};
~~~
### 下面是执行程序的结果显示:
### 1、情况显示
![](https://box.kancloud.cn/2016-08-24_57bd7796a783f.jpg)
### 2、情况显示
![](https://box.kancloud.cn/2016-08-24_57bd7796bf4f5.jpg)
### 3、情况显示
![](https://box.kancloud.cn/2016-08-24_57bd7796d3e3b.jpg)
### 表组装:
~~~
/*File:tableBox.c
*Date:2013-11-27
*Author:sjin
*Mail:413977243@qq.com
*/
#include <stdio.h>
#include <gtk/gtk.h>
#include <stdlib.h>
/*回调函数
*传到这个函数的数据将呗打印到标准输出
* */
void callback(GtkWidget *widget, gpointer data)
{
g_print("Hello again -%s was pressed\n",(char *) data);
}
/*退出回调函数*/
gint delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{
gtk_main_quit();
return FALSE;
}
int main(int argc,char *argv[])
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *table;
/*初始化*/
gtk_init(&argc,&argv);
/*创建窗口*/
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/*这个一般必要有delete_event信号到主窗口*/
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);
/*设置窗口宽度*/
gtk_container_set_border_width(GTK_CONTAINER(window),80);
/*设置窗口标题*/
gtk_window_set_title(GTK_WINDOW(window),"表组装练习");
/* 创建一个2X2的表
*GtkWidget *gtk_table_new(guint rows,guint columns,gboolean homogeneous);
*rows:表中要安排的行数
*columns:表中要安排的列数
*homogeneous:TRUE标示表格框的大小都将调整为表中最大构件的大小。
* FALSE每个表格框将会按照同行中最高的构件,与同列中最宽的构件来决定自身的大小
* */
table = gtk_table_new(2,2,TRUE);
/*将表放进主窗口*/
gtk_container_add(GTK_CONTAINER(window),table);
/*创建一个按钮*/
button = gtk_button_new_with_label("love you!");
/*将按钮设置回调函数*/
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback),(gpointer)"I love you songsong!");
/*将button插入表的左上象限
*void gtk_table_attach(GtkTable *table,已经创建的表
*GtkWidget *child,想放进表里的构件
*guint left_attach,构件的放置位置
*guint right_attach,
*guint top_attach,
*guint bottom_attach,
*GtkAttachOptions xoptions,下面是用来指定组装时的选项GTK_FILL:构件会扩展以是用所有可用空间
*GtkAttachOptions yoptions,GTK_SHRINK:构件会和表一个缩小 GTK_EXPAND:
*guint xpadding,下面2个padding,构件周围的空白区域
*guint ypadding);
*这里有个简写的函数
*void gtk_table_attach_defaults();
*默认缺省参数options:GTK_FILL|GTK_EXPAND padding:为0;
*
* */
gtk_table_attach_defaults(GTK_TABLE(table),button,0,1,0,1);
gtk_widget_show(button);
/*创建第二个按钮*/
button = gtk_button_new_with_label("miss you!");
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback),(gpointer)"I miss you songsong!");
gtk_table_attach_defaults(GTK_TABLE(table),button,1,2,0,1);
gtk_widget_show(button);
/*创建quit按钮*/
button = gtk_button_new_with_label("quit");
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(delete_event),NULL);
gtk_table_attach_defaults(GTK_TABLE(table),button,0,2,1,2);
gtk_widget_show(button);
gtk_widget_show(table);
gtk_widget_show(window);
gtk_main();
return 0;
}
~~~
运行如下:
![](https://box.kancloud.cn/2016-08-24_57bd7796ea9a9.jpg)