### 構件概述
在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、情況顯示

### 2、情況顯示

### 3、情況顯示?

### 表組裝:
~~~
/*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;
}
~~~
運行如下:
