1. 程式人生 > >GTK+(2)--視窗中新增五臟六腑

GTK+(2)--視窗中新增五臟六腑

在我們第一講當中的視窗中,我們僅僅就是學習瞭如何使用GTK+建立一個空白的視窗,但是僅僅一個空白視窗是沒有用的,我們總是需要設定視窗的屬性和向視窗中新增一些子控制元件,包括應用程式的圖示,選單,工具欄等等內容.

下面的一段程式是設定我們的視窗的一些屬性,包括設定視窗的標題,視窗的大小,視窗在螢幕中的位置等等屬性.下面看一下程式碼:

#include <gtk/gtk.h>
#include <stdio.h>
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),"bobo_GTK_Hello"); //設定使用者是否可以重新更改視窗的大小 gtk_window_set_resizable(GTK_WINDOW(window),TRUE); //可以更改大小 //gtk_window_set_resizable(GTK_WINDOW(window),FALSE); //不可更改 //獲取當前window視窗能否改變大小 gboolean canResize = gtk_window_get_resizable(GTK_WINDOW(window)); //設定視窗的大小
gtk_window_set_default_size(GTK_WINDOW(window),230,150); //設定視窗位置在螢幕中心 gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); /** * 現在我們看一下gtk_window_set_position的函式原型 * void gtk_window_set_position (GtkWindow *window,GtkWindowPosition position); * 而GtkWindowPosition是一個列舉型別的變數 * typedef enum * { * GTK_WIN_POS_NONE, //不產生任何影響 * GTK_WIN_POS_CENTER, //視窗被放置的螢幕中央 * GTK_WIN_POS_MOUSE, //視窗被放置在當前滑鼠的位置 * GTK_WIN_POS_CENTER_ALWAYS, //當視窗改變大小之後也在螢幕中央 * GTK_WIN_POS_CENTER_ON_PARENT //在他父視窗的中央 * } GtkWindowPosition; * * * */
gtk_widget_show(window); //設定程式退出的訊號 g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL); gtk_main(); return 0; }

下面是這段程式的執行程式碼:

其中,那個設定退出訊號我們後面會專門講解.

下面我們學習一個視窗中,應用程式圖示的製作.
先看下面為程式新增圖示的程式碼:

#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar * filename)
{
    GdkPixbuf *pixbuf;
    GError *error = NULL;
    pixbuf = gdk_pixbuf_new_from_file(filename,&error);

    if(!pixbuf){
        fprintf(stderr,"%s
",error->message);
        g_error_free(error);
    }
    return pixbuf;
}
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),"bobo_GTK_Hello");
    //設定使用者是否可以重新更改視窗的大小
    gtk_window_set_resizable(GTK_WINDOW(window),TRUE);  //可以更改大小
    //gtk_window_set_resizable(GTK_WINDOW(window),FALSE); //不可更改
    //獲取當前window視窗能否改變大小
    gboolean canResize = gtk_window_get_resizable(GTK_WINDOW(window));

    //設定視窗的大小
    gtk_window_set_default_size(GTK_WINDOW(window),230,150);

    //設定視窗位置在螢幕中心
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    /**
     * 現在我們看一下gtk_window_set_position的函式原型
     * void gtk_window_set_position (GtkWindow *window,GtkWindowPosition position);
     * 而GtkWindowPosition是一個列舉型別的變數
     * typedef enum
     * { 
     *  GTK_WIN_POS_NONE,  //不產生任何影響
     *  GTK_WIN_POS_CENTER, //視窗被放置的螢幕中央
     *  GTK_WIN_POS_MOUSE, //視窗被放置在當前滑鼠的位置
     *  GTK_WIN_POS_CENTER_ALWAYS, //當視窗改變大小之後也在螢幕中央
     *  GTK_WIN_POS_CENTER_ON_PARE_POS_NONE,  //不產生NT //在他父視窗的中央
     * } GtkWindowPosition;
     *
     *
     *
     */
    //設定程式圖示
    gtk_window_set_icon(GTK_WINDOW(window),create_pixbuf("bobo.png"));

    gtk_widget_show(window);
    //設定程式退出的訊號
    g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);

    gtk_main();
    return 0;
}

create_picbuf()函式的作用是從檔案中讀取圖片檔案,生成GdkPixbuf資料型別.下面我們看一下其中主要的函式
gdk_pixbuf_new_from_file()的定義.

GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error);
GdkPixbuf * gdk_pixbuf_new_from_file (const char *filename, GError **error);

意思就是:通過從檔案中載入一個影象來建立一個新的pixbuf物件.檔案的格式是自動檢測的.如果返回值是NULL的話,error引數將會
被設定,可能的錯誤在GDK_PIXBUF_ERROR和G_FILE_ERROR域中.
​filename引數: 要被載入的檔案的名稱
​error引數:返回一個錯誤的位置
​返回值:將會返回一個新建立的pixbuf物件,並且該物件的引用數為1,或者是返回NULL如果發生下面的錯誤的話:檔案無法開啟,無法識別的 ​檔案格式,沒有足夠的記憶體來載入該圖片,或者是圖片檔案包含無效的資料

下面是程式的執行結果:

好了,對視窗的屬性設定也瞭解的差不多了,現在我們設計一個小程式,學習向視窗中新增按鈕等元件.

我們這個小程式向視窗中新增兩個按鈕和一個標籤,標籤的初始數為0,兩個按鈕分別控制標籤中數字的增大和縮小.

下面請看一下實現的程式碼:

#include <gtk/gtk.h>
gint count = 0;
char buf[5];
void increase(GtkWidget *widget,gpointer label){
    count++;
    sprintf(buf,"%d",count);
    gtk_label_set_text(label,buf);
}
void decrease(GtkWidget *widget,gpointer label){
    count--;

    sprintf(buf,"%d",count);

    gtk_label_set_text(label,buf);
}
int main(int argc,char *argv[])
{
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *frame;
    GtkWidget *plus;
    GtkWidget *minus;

    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title(GTK_WINDOW(window),"a little program");
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window),250,180);

    frame = gtk_fixed_new();

    gtk_container_add(GTK_CONTAINER(window),frame);

    plus = gtk_button_new_with_label("+");
    gtk_widget_set_size_request(plus,80,35);
    gtk_fixed_put(GTK_FIXED(frame),plus,50,20);

    minus = gtk_button_new_with_label("-");
    gtk_widget_set_size_request(minus,80,35);
    gtk_fixed_put(GTK_FIXED(frame),minus,50,80);

    label = gtk_label_new("0");
    gtk_fixed_put(GTK_FIXED(frame),label,190,58);

    gtk_widget_show_all(window);

    g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
    g_signal_connect(plus,"clicked",G_CALLBACK(increase),label);
    g_signal_connect(minus,"clicked",G_CALLBACK(decrease),label);
    gtk_main();
    return 0;
}

注意這個地方,g_signal_connect(plus,”clicked”,G_CALLBACK(increase),label);
我們把回撥函式increase()和增加按鈕繫結,這個地方我們把label作為回撥函式的引數.這樣,在回撥函式increase()裡面就能對label進行處理了.

對程式元件新增監聽機制我打算在後面的講解中專門拿出一節來講解,主要講解一下GTK+訊號機制的原理以及使用方法。

下面是程式的執行結果: