linux学习记录
分类:
2008-09-22 13:37:11
●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 );
它们与第一套函数的区别是回调函数只使用一个参量。
GTK 的事件:
gtk组件的行为或X服务器发送的事件可以和下列事件联系起来
button_press_event //按钮按下
button_release_event //按钮释放
motion_notify_event //鼠标移动
delete_event //使用窗口管理器关闭
destroy_event //关闭
expose_event //曝光
key_press_event //按键按下
key_release_event //按键释放
enter_notify_event //鼠标指针进入组件
leave_notify_event //鼠标指针离开组件
configure_event //属性改变
focus_in_event //获得聚焦
focus_out_event //失去聚焦
map_event //映射
unmap_event //消失
property_notify_event //属性改变
selection_clear_event //选择清除
selection_request_event //选择请求
selection_notify_event //选择通知
proximity_in_event //接近
proximity_out_event //离开
drag_begin_event //拖开始
drag_request_event //拖请求
drag_end_event //拖结束
drop_enter_event //放进入
drop_leave_event //放离开
drop_data_available_event //放数据可用
上例中在窗口管理器中关闭窗口失效(它的好处是给用户一个重新确认的机会),原因是函数
gint delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
返回 TRUE,这样 GTK 组件不会发出 "destroy" 信号。
当按钮按下时,调用函数
void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit();
}
这样在主程序中的 gtk_main()便退出循环,程序随之结束。
函数gtk_init (&argc, &argv)初始化GTK程序并传递响应的命令行参数给 GTK,当参数符合时,便从列表中清除,剩下的参数再由用户处理
语句 window = gtk_window_new (GTK_WINDOW_TOPLEVEL) 创建顶级窗口, 参量的意义是:
GTK_WINDOW_TOPLEVEL: 顶级窗口
GTK_WINDOW_DIALOG: 对话框窗口
GTK_WINDOW_POPUP: 弹出式窗口,不受窗口管理器管理,即
无边界窗口