当构建一个更复杂的用户界面时,几十个或几百个小部件,在C代码中进行所有的安装工作都是麻烦的,而且改变是不可能的。
值得庆幸的是,GTK +通过使用可由GtkBuilder类解析的XML格式的UI描述来支持用户界面布局与业务逻辑的分离。
建立一个test.c文件,代码如下
#include <gtk/gtk.h> static void print_hello (GtkWidget *widget, gpointer data) { g_print ("Hello World\n"); } int main (int argc, char *argv[]) { GtkBuilder *builder; GObject *window; GObject *button; gtk_init (&argc, &argv); /* 建立一个GtkBuilder instance加载UI文件 */ builder = gtk_builder_new (); gtk_builder_add_from_file (builder, "builder.ui", NULL); /* Connect signal handlers to the constructed widgets. */ window = gtk_builder_get_object (builder, "window"); g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL); // 获取button1的对象 在UI文件中为对应的object id button = gtk_builder_get_object (builder, "button1"); g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL); button = gtk_builder_get_object (builder, "button2"); g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL); button = gtk_builder_get_object (builder, "quit"); g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL); gtk_main (); return 0; }void gtk_main()
一旦GTK+应用程序调用了gtk_main(),那么GTK+就接管了控制权。gtk_main()函数运行主循环,直到调用gtk_main_quit()函数,gtk_main()才会退出。gtk_main()函数的所有实例功能都是一样的,它们都监视同一个与X服务器的连接,都对同样的事件队列起作用。gtk_main()实例用于阻塞、 遮断一个函数的控制流直到满足某些条件。所有的Gtk+程序都用这个技巧使应用程序正在运行时main()函数不能退出去。与while(1)类似
void gtk_main_quit() gtk_main_quit()会使gtk_main()跳出循环并返回。 GTK+允许gtk_main()嵌套,每个gtk_main()调用必须对应于一个gtk_main_quit()调用。
guint gtk_main_level() gtk_main_level()用来判断gtk_main()当前级别。 如果返回0,说明没有在gtk_main()环境中执行应用程序。如果返回1,说明有一个单独的gtk_main()调用存在,等等。
gint gtk_main_iteration() gtk_main_iteration()会使GTK+只在主循环中通过一次,处理下一个事件并允许构件调用信号函数,但是不会调用init和quit函数
类似XML的格式,至于其中的照着写就行了,后面的我也还没了解到。。。
<interface> <object id="window" class="GtkWindow"> <property name="visible">True</property> <property name="title">Grid</property> <property name="border-width">10</property> <child> <object id="grid" class="GtkGrid"> <property name="visible">True</property> <child> <object id="button1" class="GtkButton"> <property name="visible">True</property> <property name="label">First Button</property> </object> <packing> <property name="left-attach">0</property> <property name="top-attach">0</property> </packing> </child> <child> <object id="button2" class="GtkButton"> <property name="visible">True</property> <property name="label">Second Button</property> </object> <packing> <property name="left-attach">1</property> <property name="top-attach">0</property> </packing> </child> <child> <object id="quit" class="GtkButton"> <property name="visible">True</property> <property name="label">Quit</property> </object> <packing> <property name="left-attach">0</property> <property name="top-attach">1</property> <property name="width">2</property> </packing> </child> </object> <packing> </packing> </child> </object> </interface>请注意,GtkBuilder还可以用于构造不是小部件的对象,如树模型,调整等。这就是我们在这里使用的方法被调用 gtk_builder_get_object()并返回一个GObject 而不是GtkWidget *的原因。 通常,您将传递一个完整的路径, gtk_builder_add_from_file()使程序的执行与当前目录无关。安装UI说明和类似数据的常见位置是 。 /usr/share/appname 也可以将源代码中的UI描述作为字符串嵌入并用于gtk_builder_add_from_string()加载它。但是将UI描述保存在单独的文件中有几个优点:然后可以对UI进行微调,而无需重新编译程序,更重要的是,图形UI编辑器(如glade) 可以加载文件,并允许您创建和通过点击鼠标来修改您的用户界面。*