4.2.2 GTK 编程基本示例
4.2.2 GTK 编程基本示例
●GTK 简单编程
下面的例子是一个GTK最基本例子,它仅仅在屏幕上弹出一个窗口,并且
即使关闭该窗口,该程序仍未退出。
/* File: base.c */
#include
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
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程序的基本步骤:
- 初始化
- 创建主窗口
- 创建并加入子窗口
- 设置组件回调
- 显示窗口
- 进入事件循环
●GTK中文程序示例
上面的例子是英文编程的基本例子,如果在程序中使用中文,还应当
对上面的例子作适当的修改。当然最基本的要求还是Linux系统必须有
一个正确的国际化环境,具体地说就是:
- 系统支持中文C Locale
- 系统支持中文X Locale
- GTK的资源文件/etc/gtk/gtkrc.zh_CN设置正确
对于上面的几个要求,可以参阅本书的国际化编程部分。
下面是一个典型的 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
#
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 ("大家好!");
程序运行的结果是:
如果不想用缺省的资源文件中所指定的字体,也可以在程序中指定
资源文件或直接把fontset写在程序中。 指定资源文件使用函数
gtk_rc_parse(filename),直接使用fontset使用函数
gtk_rc_parse_string (gtkrc_string)。
●实例详细剖析
上面的例子中,我们遇到了许多新的数据类型和回调的方式等,下面
一一剖析:
- 包含的头文件:
如果程序只涉及到gtk部分,而不是直接调用gdk的函数,只须包含
gtk/gtk.h,如涉及到gdk部分,应包含gdk/gdk.h
- 数据类型:
glib 中定义了许多数据类型如 gpointer,gint等等,它们都是比较
容易理解的。对GTK的组件(GtkWidget),类型都是GtkWidget,它包含了一个
窗口组件所需要的信息。GdkEvent 则封装了X事件的信息。
- 信号和回调
信号(Signal)是GTK中出现的新的并且比较重要的概念。这里讲的"信号"
不同于UNIX的signal,只是名称一样。当处理X事件时,如鼠标按键按下,
GTK的组件接收到这一事件,便发出响应的信号。不同的组件相关信号
可能不一样。
在上述例子中使用函数
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 );
它们与第一套函数的区别是回调函数只使用一个参量。