Gtk+/Glade程式設計(二)--入門

ztguang發表於2016-03-30
http://jianjiaosun.blog.163.com/blog/static/13612448620110187495730/

By unanao


     本文將http://zetcode.com/tutorials/gtktutorial/中“First porgrams”一章中內容採用Glade進行介面設計的方法完成“First porgrams”的例子,並且增加一些解釋說明。
    由於“Simple example”已經在《Gtk+/Glade程式設計(一)》中實現,這裡就不再進行實現。

一、將視窗放置在螢幕中間
主要是視窗屬性的設定,在右下角處的“屬性”裡面進行設定:
Gtk+/Glade程式設計(二) - unanao - unanao
這樣可以從右下角看到視窗物件的名稱被設為:“Center”, 視窗的標題被設為“Center”, 長度為:230, 高度:150。儲存並且命名為"center.glade"。
程式碼為:
#include

int main(int argc, char *argv[])
{
    GtkBuilder *builder;
    GtkWidget *window;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "center.glade", NULL);
    window = GTK_WIDGET(gtk_builder_get_object(builder, "center"));

   //用於關閉視窗,也可以在屬性的訊號中進行設定
    g_signal_connect(GTK_WINDOW(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show(window);

    g_object_unref(builder);

    gtk_main();

    return 0;
}
編譯:
    $gcc -o center center.c `pkg-config --cflags --libs gtk+-2.0`
執行:
    $./center
Gtk+/Glade程式設計(二) - unanao - unanao
 
點選關閉按鈕可以正常關閉。
如果不使用Glade進行介面設計及生成,生成視窗並且設定屬性的步驟為:
#include

int main(int argc, char *argv[])
{
    GtkWidget *window;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "center"); //title is "window"
    gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

    gtk_widget_show(window);

    gtk_main();   

    return 0;
}

對比可知:
建立一個元件,
使用Gtk+
  • 需要new一個元件
  • 通過set進行屬性設定
使用Glade/Gtk+
  • 需要在點選生成視窗,
  • 通過屬性設定欄進行屬性設定
  • 利用GtkBuilder將生成的xml檔案加入進來即可
雖然感覺Glade/Gtk+的步驟更多,但是並沒有直接使用Gtk+繁瑣,尤其是Glade可以設計所見即所得的介面,使得編碼更加方便,更加高效!

二、應用程式的圖示
只需“常規”的設定中,找到“圖示”,選擇需要設定為圖示的圖片即可,如下圖:
Gtk+/Glade程式設計(二) - unanao - unanao
其他的設定沒有改變,Gtk+的程式碼與“一、將視窗放置在螢幕中間”的程式碼相同(如果儲存的xml的名字進行了改動,需要修改Gtk+中gtk_builder_add_from_file的檔名)
執行結果截圖:
Gtk+/Glade程式設計(二) - unanao - unanao
左上角出現了我們加入的圖示,比上面的圖都是“X”漂亮多了!^_^
 
三、加 - 減
3個子元件,1個“標籤”, 2個“按鈕”
  • “標籤” -->顯示一個整數
  • “+” , “-”—> 增加 或減小標籤上的數字。
首先設計介面:
在“頂層”中選 “視窗”
在“容器”中選 “固定的”     --用於固定按鈕和標籤,不然加入這些元件的任何一個都會充滿整個“視窗”
在控制和顯示中選“按鈕” 和  “標籤”  (標籤是黑色的,不帶下劃線的“Label”)

然後點選 選單欄最右邊的“拖拽並調整工作區部件的大小”,調整“按鈕”和“標籤的”大小及位置。
設定各個元件的屬性:
設定按鈕的標籤:
Gtk+/Glade程式設計(二) - unanao - unanao
 
設定標籤的屬性:
Gtk+/Glade程式設計(二) - unanao - unanao

最後是Gtk+程式設計:
unanao@debian:~/gui/first-programs$ cat dec_inc.c
#include

gint count = 0;
gchar buf[6];

void increase(GtkWidget *widget, GtkLabel *label)
{
    count++;
    sprintf(buf, "%d", count);
    gtk_label_set_text(label, buf);
}

void decrease(GtkWidget *widget,  GtkLabel *label)
{
    count--;
    sprintf(buf, "%d", count);
    gtk_label_set_text(label, buf);
}

int main(int argc, char *argv[])
{
    GtkBuilder *builder;
    GtkWidget *window;
    GtkWidget *plus;
    GtkWidget *minus;
    GtkWidget *result;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "dec_inc.glade", NULL);
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
    plus = GTK_WIDGET(gtk_builder_get_object(builder, "plus"));
    minus = GTK_WIDGET(gtk_builder_get_object(builder, "minus"));
    result = GTK_WIDGET(gtk_builder_get_object(builder, "label"));

    gtk_widget_show_all(window);

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(plus, "clicked", G_CALLBACK(increase), result);
    g_signal_connect(minus, "clicked", G_CALLBACK(decrease), result);

    gtk_main();

    return 0;
}
編譯:gcc -o dec_inc dec_inc.c `pkg-config --cflags --libs gtk+-2.0`
執行:./dec_inc
Gtk+/Glade程式設計(二) - unanao - unanao
 
通過點選“+”和“-”就可以改變右邊數字的值了。

四、訊號和回撥函式
    注意這裡的回撥函式和普通的函式不一樣,雖然g_signal_connect只傳了一個引數,但是回撥函式是兩個函式,我開始感覺這個例子寫的夠笨的, 本來傳了一個引數, 回撥函式居然寫了兩個引數, 我就去掉了一個引數, 結果執行結果會報錯說傳入的引數不是“標籤”。
 要使一個按鈕執行一個動作,我們需設定訊號和訊號處理函式之間的連線。可以這
樣使用函式來設定連線:

gulong g_signal_connect( gpointer      *object,
                         const gchar   *name,
                         GCallback     func,
                         gpointer      func_data );

第一個引數是要發出訊號的構件,第二個引數是你想要連線的訊號的名稱,第三個
引數是訊號被捕獲時所要呼叫的函式,第四個引數是你想傳遞給這個函式的資料。


第三個引數指定的函式叫做回撥函式:

void callback_func( GtkWidget *widget,
                    gpointer   callback_data );

第一個引數是一個指向發出訊號的構件的指標,第二個引數是一個指向資料的指標
,就是 g_signal_connect() 函式的最後一個引數。

注意上面回撥函式的宣告是一種常用的形式,有些構件的特殊訊號會用不同的呼叫
引數。

另一個呼叫在形式 helloworld 程式中使用,是:

gulong g_signal_connect_swapped( gpointer     *object,
                                 const gchar  *name,
                                 GCallback    func,
                                 gpointer     *slot_object );

g_signal_connect_swapped() 和 g_signal_connect() 相同,只是回撥函式只用
一個引數,一個指向 GTK 物件的指標。所以當使用這個函式連線訊號時,回撥函
數應該是這樣的形式

void callback_func( GtkObject *object );

這個物件常是一個構件。然而我們通常不用函式 g_signal_connect_swapped() 設
置連線。它們常被用在只接受一個單獨的構件或者物件的回撥函式中作為引數,如
同我們的 helloworld 示例中那樣。

擁有兩個設定訊號連線函式的目的是簡單的允許回撥函式有不同數目的引數。
GTK 庫中許多函式僅接受一個單獨的構件指標作為其引數,所以對於這些函式你要
用 g_signal_connect_swapped(),然而對你自己定義的函式,你需要附加的資料
提供給你的回撥函式。

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
閱讀(1194) | 評論(0) | 轉發(7) |
給主人留下些什麼吧!~~
評論熱議

相關文章