### 事件盒 The EventBox
一 些 GTK 構件沒有與之相關聯的 X 窗口,所以它們只在其父構件上顯示其外觀。由于這個原因,它們不能接收任何事件,并且,如果它們尺寸設置不正確,它們也不會自動剪裁(譯者注:裁剪就是使 構件只顯示一部分),這樣可能會把界面弄得亂糟糟的。如果要想構件接收事件,可以使用事件盒(EventBox)。
初 一看,事件盒構件好像完全沒有什么用。它在屏幕上什么也不畫,并且對事件也不做響應。但是,它有一個功能:為它的子構件提供一個 X 窗口。因為許多G T K構件并沒有相關聯的 X 窗口,所以這一點很重要。雖然沒有 X 窗口會節省內存,提高系統性能,但它也有一些弱點。沒有 X 窗口的構件不能接收事件,并且對它的任何內容不能實施剪裁。雖然事件盒構件的名稱事件盒強調了它的事件處理功能,它也能用于剪裁構件。看下面的具體代碼:

### 點擊將會退出
~~~
/*File:color.c
*Date:2014-01-06
*Author:sjin
*Mail:413977243@qq.com
*/
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <stdlib.h>
int main( int argc, char *argv[] )
{
/* GtkWidget 是構件的存儲類型 */
GtkWidget *window;
GtkWidget *event_box;
GtkWidget *label;
/* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來并且送到該程序中*/
gtk_init (&argc, &argv);
/* 創建一個新窗口 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/*設置窗口標題*/
gtk_window_set_title(GTK_WINDOW(window),"My first program helloworld!");
/**/
gtk_window_set_policy(GTK_WINDOW(window),TRUE,TRUE,TRUE);
/* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
* 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 destroy_window() 函數。
* 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
g_signal_connect (GTK_OBJECT(window), "destroy",G_CALLBACK (gtk_main_quit), (gpointer)window);
/*創建一個事件盒,并將它加到頂級窗口上*/
event_box = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(window),event_box);
gtk_widget_show(event_box);
/*創建一個長標簽*/
label = gtk_label_new("點擊這里,退出");
gtk_container_add(GTK_CONTAINER(event_box),label);
gtk_widget_show(label);
/*將標簽剪裁短*/
gtk_widget_set_size_request(label,110,20);
/**/
gtk_widget_set_events(event_box,GDK_BUTTON_PRESS_MASK);
g_signal_connect(GTK_OBJECT(event_box),"button_press_event",G_CALLBACK(gtk_main_quit),NULL);
gtk_widget_realize(event_box);
gdk_window_set_cursor(event_box->window,gdk_cursor_new(GDK_HAND1));
gtk_widget_show (window);
/* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
* 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
gtk_main ();
return 0;
}
~~~
### 固定容器 Fixed Container
固定容器(The Fixed container)允許將構件放在窗口的固定位置,這個位置是相對于固定容器的左上角的。構件的位置可以動態改變。

~~~
/*File:color.c
*Date:2014-01-07
*Author:sjin
*Mail:413977243@qq.com
*/
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>
/*用全局變量儲存固定容器里構件的位置*/
gint x = 50;
gint y = 50;
/*這個回調函數將按鈕移動到固定容器的位置*/
void move_button(GtkWidget *widget,GtkWidget *fixed)
{
x = (x + 30)%300;
y = (y + 30)%300;
gtk_fixed_move(GTK_FIXED(fixed),widget,x,y);
}
int main( int argc, char *argv[] )
{
/* GtkWidget 是構件的存儲類型 */
GtkWidget *window;
GtkWidget *button;
GtkWidget *fixed;
gint i;
/* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來并且送到該程序中*/
gtk_init (&argc, &argv);
/* 創建一個新窗口 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/*設置窗口標題*/
gtk_window_set_title(GTK_WINDOW(window),"Fixed Container");
/**/
gtk_window_set_policy(GTK_WINDOW(window),TRUE,TRUE,TRUE);
/* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
* 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 destroy_window() 函數。
* 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
g_signal_connect (GTK_OBJECT(window), "destroy",G_CALLBACK (gtk_main_quit), NULL);
/*設置窗口的邊框寬度*/
gtk_container_set_border_width(GTK_CONTAINER(window),10);
/*創建一個固定容器*/
fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window),fixed);
gtk_widget_show(fixed);
for(i = 0; i < 3; i++){
/*創建一個按鈕*/
button = gtk_button_new_with_label("miss you!");
g_signal_connect(GTK_OBJECT(button),"clicked",G_CALLBACK(move_button),fixed);
/*將按鈕組裝到一個固定容器的窗口中*/
gtk_fixed_put(GTK_FIXED(fixed),button,i*50,i*50);
gtk_widget_show(button);
}
gtk_widget_show (window);
/* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
* 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
gtk_main ();
return 0;
}
~~~