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

 

 

 

 

 

posted on 2020-03-20 14:55  陌鉎こ城sHi  阅读(6831)  评论(0编辑  收藏  举报