Linux 下从头再走 GTK+-3.0 (五)
实践中表明,纯粹利用 gtk 函数来创建 UI 是很繁琐的事,需要编写很多代码。怎样才能快速统一的建立 UI 布局呢?
可喜的是 GTK 提供了一个 GtkBuilder 用于快速创建界面。它读取一个 xml 文件。按照 xml 文件中所描述的来创建界面。因此我们需要编写 xml 文件。
创建example.ui ,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <interface> <object id="window" class="GtkWindow"> <property name="visible">True</property> <property name="title">GtkBuilder</property> <property name="border-width">30</property> <child> <object id="grid" class="GtkGrid"> <property name="visible">True</property> <child> <object id="print_hello" class="GtkButton"> <property name="visible">True</property> <property name="label">Button 1</property> </object> <packing> <property name="left-attach">0</property> <property name="top-attach">0</property> </packing> </child> <child> <object id="print_entry" class="GtkButton"> <property name="visible">True</property> <property name="label">Button 2</property> </object> <packing> <property name="left-attach">1</property> <property name="top-attach">0</property> </packing> </child> <child> <object id="entry" class="GtkEntry"> <property name="visible">True</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>
再创建源文件 example.c ,内容如下:
#include <gtk/gtk.h> static void print_hello(GtkWidget *button , gpointer data); static void activate(GtkApplication *app , gpointer data); static void print_entry(GtkWidget * button , gpointer entry); int main(int argc , char **argv) { GtkApplication *app; int app_status; app = gtk_application_new("org.rain.example" , G_APPLICATION_FLAGS_NONE); g_signal_connect(app , "activate" , G_CALLBACK(activate) , NULL); app_status = g_application_run(G_APPLICATION(app) , argc , argv); g_object_unref(app); return app_status; } static void print_hello(GtkWidget *button , gpointer data) { printf("Hello,world!\n"); } static void print_entry(GtkWidget * button , gpointer entry) { const gchar *entry_buf; //获取输入框的内容,返回一个 const gchar 指针 , gchar 即是 char entry_buf = gtk_entry_get_text( GTK_ENTRY(entry) ); if('\0' != entry_buf[0]) printf("%s\n" , entry_buf); } static void activate(GtkApplication *app , gpointer data) { GtkBuilder *builder; GObject *window; GObject *button; GObject *entry; //创建一个 GtkBuilder 。 builder = gtk_builder_new(); //将描述 UI 的文件添加到 Builder 中。 gtk_builder_add_from_file(builder , "example.ui" , NULL); //可以用该函数获取 Builder 创建的对象,根据 example.ui 文件中设置的 object 的 id 来获取。 window = gtk_builder_get_object(builder , "window"); gtk_application_add_window(app , GTK_WINDOW(window)); //注意该函数返回的是一个指向 GObject 对象的指针。 button = gtk_builder_get_object(builder , "print_hello"); //设置按钮标签 gtk_button_set_label ( GTK_BUTTON (button) , "PrintHello"); g_signal_connect(button , "clicked" , G_CALLBACK(print_hello) , NULL); //获取输入框对象。 entry = gtk_builder_get_object(builder , "entry"); button = gtk_builder_get_object(builder , "print_entry"); gtk_button_set_label ( GTK_BUTTON (button) , "PrintEntry"); //调用 print_entry 时传递用户参数 entry 。 g_signal_connect(button , "clicked" , G_CALLBACK(print_entry) , entry); }
编译,运行:
gcc example.c `pkg-config --cflags --libs gtk+-3.0` ./a.out
运行结果如下: