GTK從入門到放棄


GTK環境搭建( Linux )

安裝命令

sudo apt-get install libgtk3.0*

lin@lin-host:~$ sudo apt-get install libgtk3.0*
[sudo] password for lin: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done

 

測試是否安裝成功
pkg-config --cflags --libs gtk+-3.0
lin@lin-host:~$ pkg-config --cflags --libs gtk+-3.0
-pthread -I/usr/include/gtk-3.0 -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/libpng12  -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0  

現在我們建立簡單的一個空白窗口

 

 代碼如下

#include <gtk/gtk.h>

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

編譯方法

$ gcc main.c `pkg-config --libs --cflags gtk+-3.0`

【備注】這邊`是按鍵ESC下的

或者寫一個腳本

#!/bin/bash
gcc $1 `pkg-config --libs --cflags gtk+-3.0`

 給記得給腳本 chmod +x

執行腳本。、

$ ./cmd.sh main.c

 

測試一下我們編譯的

$ ./a.out 

 

 

現在我們修改標題欄

新增代碼如下紅色所示

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/ gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL)); /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

 現在我們添加按鍵

 

#include <gtk/gtk.h>

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
    /* 創建一個標簽為 "button" 的新按鈕。*/ button = gtk_button_new_with_label ("button"); /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (window), button);

    /* 最后一步是顯示新創建的按鈕*/ gtk_widget_show (button); /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

 現在我們在按鍵點擊輸出一些信息

 

#include <gtk/gtk.h>

/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    g_print ("Hello World  %s\n",(gchar *) data);
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
    /* 設置窗口邊框的寬度。*/ gtk_container_set_border_width (GTK_CONTAINER (window), 10); /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "GTK");

    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (window), button);

    /* 最后一步是顯示新創建的按鈕*/
    gtk_widget_show (button);

   /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

現在我們增加關閉窗口提示信息

 

 

#include <gtk/gtk.h>

/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    g_print ("Hello World  %s\n",(gchar *) data);
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);




    /* 創建一個標簽為 "Hello World" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "GTK");

    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (window), button);

    /* 最后一步是顯示新創建的按鈕*/
    gtk_widget_show (button);

   /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

現在我們該為按鍵來控制關閉

 

 

#include <gtk/gtk.h>

/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    g_print ("Hello World  %s\n",(gchar *) data);
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);




    /* 創建一個標簽為 "Hello World" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");
#if 0
    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "GTK");
#else
 /* 當點擊按鈕時,會通過調用 gtk_widget_destroy(window) 來關閉窗口。
     * "destroy" 信號會從這里或從窗口管理器發出。*/
     g_signal_connect_swapped (G_OBJECT (button), "clicked",
                               G_CALLBACK (gtk_widget_destroy),window);
#endif
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (window), button);

    /* 最后一步是顯示新創建的按鈕*/
    gtk_widget_show (button);

   /* 最后一步是顯示新創建的窗口 */
    gtk_widget_show (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}

我們新增兩個按鍵

 

 

#include <gtk/gtk.h>

/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    g_print ("Hello World  %s\n",(gchar *) data);
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;
    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));

    /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
      * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
      * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


    /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
      * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
      * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

    /* 我們創建了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
#if 0
    box1 = gtk_hbox_new (FALSE, 1); //GTK2.0支持
#else
    box1 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);//GTK3.0推薦
#endif
    /* 把組裝盒放入主窗口中。*/
    gtk_container_add (GTK_CONTAINER (window), box1);

    /* 創建一個標簽為 "button" 的新按鈕。*/ button = gtk_button_new_with_label ("button"); /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給 * 它作為參數。hello() 函數在前面定義了。*/ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), "1"); /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/ gtk_container_add (GTK_CONTAINER (box1), button); /* 顯示新創建的按鈕*/ gtk_widget_show (button); /* 創建一個標簽為 "button" 的新按鈕。*/ button = gtk_button_new_with_label ("button"); /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給 * 它作為參數。hello() 函數在前面定義了。*/ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), "2"); /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/ gtk_container_add (GTK_CONTAINER (box1), button); /* 顯示新創建的按鈕*/ gtk_widget_show (button); /* 創建一個標簽為 "button" 的新按鈕。*/ button = gtk_button_new_with_label ("button"); /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給 * 它作為參數。hello() 函數在前面定義了。*/ g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), "3"); #if 0 /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/ gtk_container_add (GTK_CONTAINER (box1), button); #else /* 代替 gtk_container_add,我們把按鈕放入不可見的組裝盒,該組合盒已經組裝進窗口中了。*/ gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0); #endif

/* 顯示新創建的按鈕*/ gtk_widget_show (button); gtk_widget_show (box1); /* 最后一步是顯示新創建的窗口 */ gtk_widget_show (window); /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里 * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/ gtk_main (); return 0; }

 

 現在我們增加label來顯示按鍵的信息

 

將使用到的函數

GtkWidget *gtk_label_new (const gchar *str);

void gtk_label_set_text (GtkLabel *label,const gchar *str);

代碼如下

#include <gtk/gtk.h>

/*聲明全局變量label*/
GtkWidget *label;
/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    g_print ("Hello World  %s\n",(gchar *) data);
    gtk_label_set_text (GTK_LABEL(label),(gchar *) data);
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;
    GtkWidget *box2;
    GtkWidget *box3;
    

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);


     /* 我們創建了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
      box1 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);//GTK3.0
      box2 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
      box3 =gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    /* 把組裝盒放入主窗口中。*/
     gtk_container_add (GTK_CONTAINER (window), box3);
    
     gtk_container_add (GTK_CONTAINER (box3), box1);
     gtk_container_add (GTK_CONTAINER (box3), box2);

    /*創建標簽*/
    label  = gtk_label_new("label");
    /*布局容器里*/
    gtk_container_add(GTK_CONTAINER(box2), label);         
    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "1");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "2");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "3");
    /* 代替 gtk_container_add,我們把按鈕放入不可見的組裝盒,該組合盒已經組裝進窗口中了。*/
    gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);

   /* 顯示 */
    gtk_widget_show_all (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}
View Code

 我們現在在原來基礎上使用g_string_printf

 

GString *g_string_new (const gchar *init);
void g_string_printf (GString *string,
                 const gchar *format,
                 ...);
gchar *g_string_free (GString *string,
               gboolean free_segment);

 

 代碼如下

#include <gtk/gtk.h>

/*聲明全局變量label*/
GtkWidget *label;
/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    GString *string=g_string_new (NULL);
    g_print ("Hello World  %s\n",(gchar *) data);
    g_string_printf(string,"Hello World  %s\n", (gchar *) data);
    gtk_label_set_text (GTK_LABEL(label),string->str);
    g_string_free(string, TRUE); 
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;
    GtkWidget *box2;
    GtkWidget *box3;
    

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);


     /* 我們創建了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
      box1 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);//GTK3.0
      box2 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
      box3 =gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    /* 把組裝盒放入主窗口中。*/
     gtk_container_add (GTK_CONTAINER (window), box3);

     gtk_container_add (GTK_CONTAINER (box3), box1);
     gtk_container_add (GTK_CONTAINER (box3), box2);

    /*創建標簽*/
    label  = gtk_label_new("label");
    /*布局容器里*/
    gtk_container_add(GTK_CONTAINER(box2), label);         
    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "1");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "2");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "3");
    /* 代替 gtk_container_add,我們把按鈕放入不可見的組裝盒,該組合盒已經組裝進窗口中了。*/
    gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);

   /* 顯示 */
    gtk_widget_show_all (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}
View Code

 

現在添加鼠標事件

void gtk_widget_add_events (GtkWidget *widget, gint events);

 

 

 代碼如下

#include <gtk/gtk.h>

/*聲明全局變量label*/
GtkWidget *label;
/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    GString *string=g_string_new (NULL);
    g_print ("Hello World  %s\n",(gchar *) data);
    g_string_printf(string,"Hello World  %s\n", (gchar *) data);
    gtk_label_set_text (GTK_LABEL(label),string->str);
    g_string_free(string, TRUE); 
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

// 鼠標點擊事件處理函數
gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    switch(event->button){    // 判斷鼠標點擊的類型
        case 1:
            g_print ("Left Button!!\n");
            break;
        case 2:
            g_print ("Middle Button!!\n");
            break;
        case 3:
            g_print ("Right Button!!\n");
            break;
        default:
            g_print ("Unknown Button!!\n");
    }
 
    if(event->type == GDK_2BUTTON_PRESS){
        g_print ("double click\n");
    }
 
    // 獲得點擊的坐標值,距離窗口左頂點
    gint i = event->x;
    gint j = event->y;
    g_print ("press_x = %d, press_y = %d\n", i, j);
 
    return TRUE;
}
 
// 鼠標移動事件(點擊鼠標任何鍵)的處理函數
gboolean deal_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
    // 獲得移動鼠標的坐標值,距離窗口左頂點
    gint i = event->x;
    gint j = event->y;
    g_print ("motion_x = %d, motion_y = %d\n", i, j);
    
    return TRUE;
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;
    GtkWidget *box2;
    GtkWidget *box3;
    

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);


     /* 我們創建了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
      box1 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);//GTK3.0
      box2 =gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
      box3 =gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    /* 把組裝盒放入主窗口中。*/
     gtk_container_add (GTK_CONTAINER (window), box3);

     gtk_container_add (GTK_CONTAINER (box3), box1);
     gtk_container_add (GTK_CONTAINER (box3), box2);

    /*創建標簽*/
    label  = gtk_label_new("label");
    /*布局容器里*/
    gtk_container_add(GTK_CONTAINER(box2), label);         
    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "1");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "2");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_container_add (GTK_CONTAINER (box1), button);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "3");
    /* 代替 gtk_container_add,我們把按鈕放入不可見的組裝盒,該組合盒已經組裝進窗口中了。*/
    gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);


    /*窗口接收鼠標事件*/
   // GDK_BUTTON_PRESS_MASK:鼠標點擊事件
   // GDK_BUTTON_MOTION_MASK:按住鼠標移動事件
   gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK);

    // "button-press-event" 與 deal_mouse_event 連接,鼠標點擊事件
   g_signal_connect(window, "button-press-event", G_CALLBACK(deal_mouse_press), NULL);
   // "motion-notify-event" 與 deal_motion_notify_event 連接,按住鼠標移動事件
   g_signal_connect(window, "motion-notify-event", G_CALLBACK(deal_motion_notify_event), NULL);
 

   /* 顯示 */
    gtk_widget_show_all (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}
View Code

 

【知識點】關於GTK的信號量和事件可以參考https://www.cnblogs.com/tianshuai11/archive/2012/01/05/2477206.html

使用grid的來布局

主要函數

GtkWidget *gtk_grid_new (void);
void gtk_grid_attach (GtkGrid *grid,
                 GtkWidget *child,
                 gint left,
                 gint top,
                 gint width,
                 gint height);

代碼如下

#include <gtk/gtk.h>

/*聲明全局變量label*/
GtkWidget *label;
/* 這是一個回調函數*/
void hello( GtkWidget *widget, gpointer   data )
{
    GString *string=g_string_new (NULL);
    g_print ("Hello World  %s\n",(gchar *) data);
    g_string_printf(string,"Hello World  %s\n", (gchar *) data);
    gtk_label_set_text (GTK_LABEL(label),string->str);
    g_string_free(string, TRUE); 
}

gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
{
    /* 如果你的 "delete_event" 信號處理函數返回 FALSE,GTK 會發出 "destroy" 信號。
     * 返回 TRUE,你不希望關閉窗口。
     * 當你想彈出“你確定要退出嗎?”對話框時它很有用。*/

    g_print ("delete event occurred\n");

    /* 改 TRUE 為 FALSE 程序會關閉。*/

    return FALSE;
}

/* 一個回調函數 */
void destroy( GtkWidget *widget, gpointer   data )
{
    g_print ("destroy event \n");
    gtk_main_quit ();
}

// 鼠標點擊事件處理函數
gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    switch(event->button){    // 判斷鼠標點擊的類型
        case 1:
            g_print ("Left Button!!\n");
            break;
        case 2:
            g_print ("Middle Button!!\n");
            break;
        case 3:
            g_print ("Right Button!!\n");
            break;
        default:
            g_print ("Unknown Button!!\n");
    }
 
    if(event->type == GDK_2BUTTON_PRESS){
        g_print ("double click\n");
    }
 
    // 獲得點擊的坐標值,距離窗口左頂點
    gint i = event->x;
    gint j = event->y;
    g_print ("press_x = %d, press_y = %d\n", i, j);
 
    return TRUE;
}
 
// 鼠標移動事件(點擊鼠標任何鍵)的處理函數
gboolean deal_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
    // 獲得移動鼠標的坐標值,距離窗口左頂點
    gint i = event->x;
    gint j = event->y;
    g_print ("motion_x = %d, motion_y = %d\n", i, j);
    
    return TRUE;
}

int main( int   argc, char *argv[] )
{
    /* GtkWidget 是構件的存儲類型 */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;
    GtkWidget *box2;
    GtkWidget *box3;
    GtkWidget *grid;

    /* 這個函數在所有的 GTK 程序都要調用。參數由命令行中解析出來並且送到該程序中*/
    gtk_init (&argc, &argv);

    /* 創建一個新窗口 */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);


    /* 設置title文字,注意UTF8格式的文字轉換,否則是亂碼*/
    gtk_window_set_title(GTK_WINDOW (window), g_locale_to_utf8("你好",-1,NULL,NULL,NULL));
    
   /* 當窗口收到 "delete_event" 信號 (這個信號由窗口管理器發出,通常是“關閉”
     * 選項或是標題欄上的關閉按鈕發出的),我們讓它調用在前面定義的 delete_event() 函數。
     * 傳給回調函數的 data 參數值是 NULL,它會被回調函數忽略。*/
    g_signal_connect (G_OBJECT (window), "delete_event",
                      G_CALLBACK (delete_event), NULL);


   /* 在這里我們連接 "destroy" 事件到一個信號處理函數。
     * 對這個窗口調用 gtk_widget_destroy() 函數或在 "delete_event" 回調函數中返回 FALSE 值
     * 都會觸發這個事件。*/
    g_signal_connect (G_OBJECT (window), "destroy",
                      G_CALLBACK (destroy), NULL);

    /* 設置窗口邊框的寬度。*/
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);


     /* 我們創建了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
    grid = gtk_grid_new ();
    /* 把組裝盒放入主窗口中。*/
    gtk_container_add (GTK_CONTAINER (window), grid);


     
    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "1");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "2");
    /* 把按鈕放入窗口 (一個 gtk 容器) 中。*/
    gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
    /* 顯示新創建的按鈕*/
    gtk_widget_show (button);


    /* 創建一個標簽為 "button" 的新按鈕。*/
    button = gtk_button_new_with_label ("button");

    /* 當按鈕收到 "clicked" 信號時會調用 hello() 函數,並將NULL傳給
     * 它作為參數。hello() 函數在前面定義了。*/
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (hello), "3");
    gtk_grid_attach (GTK_GRID (grid), button, 2, 0, 1, 1);


   /*創建標簽*/
    label  = gtk_label_new("label");
    /*布局容器里*/
    gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 3, 1);    
    

    /*窗口接收鼠標事件*/
   // GDK_BUTTON_PRESS_MASK:鼠標點擊事件
   // GDK_BUTTON_MOTION_MASK:按住鼠標移動事件
   gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK);

    // "button-press-event" 與 deal_mouse_event 連接,鼠標點擊事件
   g_signal_connect(window, "button-press-event", G_CALLBACK(deal_mouse_press), NULL);
   // "motion-notify-event" 與 deal_motion_notify_event 連接,按住鼠標移動事件
   g_signal_connect(window, "motion-notify-event", G_CALLBACK(deal_motion_notify_event), NULL);
 

   /* 顯示 */
    gtk_widget_show_all (window);

    /* 所有的 GTK 程序必須有一個 gtk_main() 函數。程序運行停在這里
     * 等待事件 (如鍵盤事件或鼠標事件) 的發生。*/
    gtk_main ();

    return 0;
}
View Code

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM