--------------------------------------------------------------------------------
3. 下一步
3.1 資料型態
有些東西您可能在前面的范例中已經看到, 這需要多解釋一下. 像gint, gchar等等. 這些是為了取得絕對乾淨的獨立性, 如資料大小等等. 像"gint32"就是個很好的范例, 其目的是維持到任意平台均為32bits, 不管是64 bit alpha或是32 bit i386. 其定義是極其直接而且直覺的. 它們都被定義在glib/glib.h (被gtk.h所include).
您也看到像在GtkWidget這一類的東西. GTK是物件導向的設計, 而widget則是其中的物件.
3.2 更多關於信號處理函數
我們來看看gtk_signal_connect宣告.
gint gtk_signal_connect (GtkObject *object, gchar *name,
GtkSignalFunc func, gpointer func_data);
看到gint的返回值? 這是個標明您的callback函數的標簽值. 像之前所說的, 每個信號及物件可以有好幾個callback, 每個會以它們所接上的順序被輪流執行到. 您可以用以下這個函數來移除這個callback函數:
void gtk_signal_disconnect (GtkObject *object,
gint id);
你可以透過您想要移除的widget handler,給定id, 來解除信號處理函數.
您也可以用:
gtk_signal_disconnect_by_data (GtkObject *object,
gpointer data);
這玩意我倒沒用過, 我真得不曉得要怎麼用 :)
另一個函數可以解除所有的處理函數:
gtk_signal_handlers_destroy (GtkObject *object);
這個函數到底是自己解釋了自己的功能. 它移除了該物件所有的信號處理函數.
3.3 Hello World的加強版
我們來看看一個稍經改良的hello world, 這是個callback的不錯的例子. 這也會介紹到我們下一個主題, 封裝物件.
#include
/* 新改進的callback. 輸入到該函數的資料被輸出到. */
void callback (GtkWidget *widget, gpointer *data)
{
g_print ("Hello again - %s was pressed\n", (char *) data);
}
/* another callback */
void destroy (GtkWidget *widget, gpointer *data)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
/* GtkWidget is the storage type for widgets */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
/* this is called in all GTK applications. arguments are parsed from
* the command line and are returned to the application. */
gtk_init (&argc, &argv);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* 這是個新函數, 它設定title到新視窗上"Hello Buttons!" */
gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");
/* 用這樣會比較簡單一點. */
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (destroy), NULL);
/* 設定邊框寬度. */
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* 我們產生一個box來封裝物件. 這一點會在"packing"詳述.
這個box實際上看不見, 它只是用來當成是個工具來安排物件 */
box1 = gtk_hbox_new(FALSE, 0);
/* 將box放到主視窗中. */
gtk_container_add (GTK_CONTAINER (window), box1);
/* 產生一個新按鈕並帶有標簽"Button 1". */
button = gtk_button_new_with_label ("Button 1");
/* 當按鈕被按下的時候, 我們呼叫"callback"函數
* 並以其指標做為參數送到"button 1" */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "button 1");
/* instead of gtk_container_add, we pack this button into the invisible
* box, which has been packed into the window. */
gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
/* always remember this step, this tells GTK that our preparation for
* this button is complete, and it can be displayed now. */
gtk_widget_show(button);
/* do these same steps again to create a second button */
button = gtk_button_new_with_label ("Button 2");
/* call the same callback function with a different argument,
* passing a pointer to "button 2" instead. */
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (callback), (gpointer) "button 2");
gtk_box_pack_start(GTK_BOX(box1), button, TRUE, TRUE, 0);
/* The order in which we show the buttons is not really important, but I
* recommend showing the window last, so it all pops up at once. */
gtk_widget_show(button);
gtk_widget_show(box1);
gtk_widget_show (window);
/* rest in gtk_main and wait for the fun to begin! */
gtk_main ();
return 0;
}
將這個程式以相同的參數編譯, 您會看到沒有任何方法來離開程式, 您必須使用視窗管理程式或命令列來殺掉它. 對讀者來說, 加個"Quit"按鈕會是個不錯的練習. 您也可以玩一玩gtk_box_pack_start()這個東西. 試試拉一拉視窗, 看看有什麼變換.
另外有個蠻有用的define給gtk_window_new()用 - GTK_WINDOW_DIALOG. 它的互動行為有點不太一樣.
--------------------------------------------------------------------------------
(http://www.fanqiang.com)
進入【UNIX論壇】
|