天天看點

GTK+(2)--視窗中添加五髒六腑

版權聲明:您好,轉載請留下本人部落格的位址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/45900409

在我們第一講當中的視窗中,我們僅僅就是學習了如何使用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+信号機制的原理以及使用方法。

繼續閱讀