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系统必须有 一个正确的国际化环境,具体地说就是:

 

  • 系统支持中文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 <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)。

 

●实例详细剖析

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

 

  • 包含的头文件:

    如果程序只涉及到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: 弹出式窗口,不受窗口管理器管理,即 无边界窗口
  • 语句 gtk_container_set_border_width (GTK_CONTAINER (window), 10) 把窗口的内边界宽度设置为10。
  • 语句 gtk_container_add (GTK_CONTAINER (window), button) 把刚建立 的按钮组件加入到 window 中。请注意这里在使用 window 时把它投影 成GTK_CONTAINER,在以后的GTK编程中会经常遇到类似的投影。
  • 语句 gtk_widget_show (window); 表示已经设置完窗口的属性,可以显示 了。
  • 事件循环 gtk_main(),由 GTK 内部处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值