• 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
    ",(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
    ",(gchar *) data);
    }
    
    gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
    {
        /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。
         * 返回 TRUE,你不希望关闭窗口。
         * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/
    
        g_print ("delete event occurred
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        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
    ",(gchar *) data);
    }
    
    gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
    {
        /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。
         * 返回 TRUE,你不希望关闭窗口。
         * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/
    
        g_print ("delete event occurred
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        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
    ",(gchar *) data);
    }
    
    gint delete_event( GtkWidget *widget, GdkEvent  *event, gpointer   data )
    {
        /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。
         * 返回 TRUE,你不希望关闭窗口。
         * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/
    
        g_print ("delete event occurred
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        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
    ",(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
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        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
    ",(gchar *) data);
        g_string_printf(string,"Hello World  %s
    ", (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
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        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
    ",(gchar *) data);
        g_string_printf(string,"Hello World  %s
    ", (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
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        gtk_main_quit ();
    }
    
    // 鼠标点击事件处理函数
    gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
    {
        switch(event->button){    // 判断鼠标点击的类型
            case 1:
                g_print ("Left Button!!
    ");
                break;
            case 2:
                g_print ("Middle Button!!
    ");
                break;
            case 3:
                g_print ("Right Button!!
    ");
                break;
            default:
                g_print ("Unknown Button!!
    ");
        }
     
        if(event->type == GDK_2BUTTON_PRESS){
            g_print ("double click
    ");
        }
     
        // 获得点击的坐标值,距离窗口左顶点
        gint i = event->x;
        gint j = event->y;
        g_print ("press_x = %d, press_y = %d
    ", 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
    ", 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
    ",(gchar *) data);
        g_string_printf(string,"Hello World  %s
    ", (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
    ");
    
        /* 改 TRUE 为 FALSE 程序会关闭。*/
    
        return FALSE;
    }
    
    /* 一个回调函数 */
    void destroy( GtkWidget *widget, gpointer   data )
    {
        g_print ("destroy event 
    ");
        gtk_main_quit ();
    }
    
    // 鼠标点击事件处理函数
    gboolean deal_mouse_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
    {
        switch(event->button){    // 判断鼠标点击的类型
            case 1:
                g_print ("Left Button!!
    ");
                break;
            case 2:
                g_print ("Middle Button!!
    ");
                break;
            case 3:
                g_print ("Right Button!!
    ");
                break;
            default:
                g_print ("Unknown Button!!
    ");
        }
     
        if(event->type == GDK_2BUTTON_PRESS){
            g_print ("double click
    ");
        }
     
        // 获得点击的坐标值,距离窗口左顶点
        gint i = event->x;
        gint j = event->y;
        g_print ("press_x = %d, press_y = %d
    ", 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
    ", 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
  • 相关阅读:
  • 原文地址:https://www.cnblogs.com/libra13179/p/12531758.html
  • 最新文章
  • 热门文章
一二三 - 开发者的网上家园