4.2.2 GTK 编程基本示例

4.2.2 GTK 编程基本示例

●GTK 简单编程

下面的例子是一个GTK最基本例子,它仅仅在屏幕上弹出一个窗口,并且 即使关闭该窗口,该程序仍未退出。

/* File: base.c */ #include <gtk/gtk.h> int main( int argc, char *argv[] ) { GtkWidget *window; gtk_init (&argc, &argv); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_show (window); gtk_main (); return(0); } 其中 gtk_init(&argc, &argv) 是gtk应用程序的初始化部分,它使gtk 应用程序可以接受某些命令行的参量: --gtk-module //载入另外的GTK模块 --g-fatal-warnings //使所有警告是致命错误 --gtk-debug //调试gtk --gtk-no-debug //不调试gtk --gdk-debug //调试gdk --gdk-no-debug //不调试gdk --display //指定display --sync //使X调用按顺序方式 --no-xshm //不使用X共享内存 --name //指定窗口管理器使用的程序名 --class //指定窗口管理器使用的程序类型 其中 window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_show (window); 建立顶级窗口并且显示该窗口,它在缺省情况下是200x200大小。

最后 gtk_main() 使程序进入事件循环阶段,gtk将在内部处理事件。

现在让我们编译文件 base.c:

gcc -Wall -g base.c -o base \ `gtk-config --cflags` `gtk-config --libs` 其中 `gtk-config --cflags` 产生编译gtk所使用的头文件位置, `gtk-config --libs` 产生连接gtk程序所使用的库。一般地,涉及 gtk的库有: libgtk.so libgdk.so libgmodule.so libglib.so。

接下来把上面的例子变成一个稍微复杂的例子,该例子弹出一个 窗口,并且在窗口中显示一个按钮。

/* File: helloworld.c */ #include <gtk/gtk.h> void hello( GtkWidget *widget, gpointer data ) { g_print ("Hello World\n"); } gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { //打印信息 g_print ("delete event occurred\n"); //如果返回FALSE,GTK将发出"destroy"信号; 如果返回TRUE, //则不让该窗口关闭 return(TRUE); } void destroy( GtkWidget *widget, gpointer data ) { gtk_main_quit(); } int main( int argc, char *argv[] ) { //GtkWidget 是 Widget的类型 GtkWidget *window; GtkWidget *button; //gtk 初始化 gtk_init(&argc, &argv); //建立新窗口 window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //当使用窗口管理器关闭窗口时,将调用 delete_event() 函数 //本例中所传递的参数是 NULL gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); //把 "destroy" 事件和信号处理器联系起来 gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (destroy), NULL); //设置窗口的边界宽度 gtk_container_set_border_width (GTK_CONTAINER (window), 10); //建立一个标签是"Hello World"的按钮 button = gtk_button_new_with_label ("Hello World"); //当按钮被单击时,即接收到"clicked"信号,将调用 hello()函数 gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (hello), NULL); //当按钮被单击时,调用 gtk_widget_destroy(window)关闭窗口。 //这里将引发 "destroy" 信号 gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (window)); //把按钮加入顶级窗口中 gtk_container_add (GTK_CONTAINER (window), button); //显示按钮 gtk_widget_show (button); //显示顶级窗口 gtk_widget_show (window); //进入事件循环 gtk_main (); return(0); } 编译连接 helloworld.c,执行结果为:

[ gtk-helloworld.gif ]

下面总结一下,编写GTK程序的基本步骤:

●GTK中文程序示例

上面的例子是英文编程的基本例子,如果在程序中使用中文,还应当 对上面的例子作适当的修改。当然最基本的要求还是Linux系统必须有 一个正确的国际化环境,具体地说就是:

对于上面的几个要求,可以参阅本书的国际化编程部分。

下面是一个典型的 gtkrc.zh_CN文件,其中指定的缺省字体是14点阵 字体。

# $(gtkconfigdir)/gtkrc.zh_CN # # This file defines the fontsets for Chinese language (zh) using # the simplified chinese standard GuoBiao as in mainland China (CN) # # 1999, Pablo Saratxaga <srtxg@chanae.alphanet.ch> # style "gtk-default-zh-cn" { fontset = "-adobe-helvetica-medium-r-normal--14-*-*-*-*-*-iso8859-*,\ -cclib-song-medium-r-normal--14-*-*-*-*-*-gbk-0" } class "GtkWidget" style "gtk-default-zh-cn" 使上述程序支持中文非常简单,只需要在初始化gtk之前调用locale设置函数: //设置Locale gtk_set_locale(); //gtk 初始化 gtk_init(&argc, &argv); 把按钮的标签改为中文即可: //建立一个含中文标签的按钮 button = gtk_button_new_with_label ("大家好!"); 程序运行的结果是:

[ gtk-helloworld-chinese.gif ]

如果不想用缺省的资源文件中所指定的字体,也可以在程序中指定 资源文件或直接把fontset写在程序中。 指定资源文件使用函数 gtk_rc_parse(filename),直接使用fontset使用函数 gtk_rc_parse_string (gtkrc_string)。

●实例详细剖析

上面的例子中,我们遇到了许多新的数据类型和回调的方式等,下面 一一剖析:

在上述例子中使用函数 gint gtk_signal_connect( GtkObject *object, gchar *name, GtkSignalFunc func, gpointer func_data ); 把组件 object 与回调函数 func 联系起来,name 是所发出的信号的 名称。func_data 是传递给回调函数的参数。

回调函数的格式是

void callback_func( GtkWidget *widget, gpointer callback_data ); 其中 widget 是发出信号的组件,callback_data 是传递参数的指针。

在上例中还使用了另外一套类似的函数:

gint gtk_signal_connect_object( GtkObject *object, gchar *name, GtkSignalFunc func, GtkObject *slot_object ); void callback_func( GtkObject *object ); 它们与第一套函数的区别是回调函数只使用一个参量。