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; }
我们现在在原来基础上使用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; }
现在添加鼠标事件
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; }
【知识点】关于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; }