构建用户界面
当构建一个更复杂的用户界面时,几十个或几百个小部件,在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函数
builder.ui文件
类似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) 可以加载文件,并允许您创建和通过点击鼠标来修改您的用户界面。*