转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 数据库 >> MySql >> 正文
Linux GUI编程笔记之GTK+篇(1)         ★★★★

Linux GUI编程笔记之GTK+篇(1)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1059 更新时间:2009/4/22 20:45:33

Linux GUI编程笔记之GTK+篇(1)
              ----信号-回调函数和事件


GTK+(GIMP Toolkit)是一个在Linux平台上比较流行的GUI构建工具,著名的Gnome平台就是基于它的。虽然它是用C语言编写的,但是它却成功的应用了面向对象和回调函数这些技术。在它的主页www.gtk.org上有一个详细的教程下载(国内有网友也做了翻译),所以我在这里也不详细的介绍它的内容了。作为自己学习GTK+编程的笔记(我现在在看英文的GTK文档),我只是着重分析一些在GTK教程上比较难懂的,然后比较关键的知识点。有什么错误纰漏的地方,请各位网友指正。


首先,让我们来看一个简单的例子,然后引出我们今天的讨论的主题:

#include <gtk/gtk.h>

/* This is a callback function */
void hello( GtkWidget *widget,
            gpointer   data )
{
    g_print ("Hello World\n");
}

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;
    GtkWidget *button;
   
 /* init the program */
    gtk_init (&argc, &argv);
   
 /* make a new button */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    g_signal_connect (G_OBJECT (window), "destroy",
        G_CALLBACK (gtk_main_quit), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
   
 /* make a new button */
    button = gtk_button_new_with_label ("Hello World");
    g_signal_connect (G_OBJECT (button), "clicked",
        G_CALLBACK (hello), NULL);
   
 /* add the button to the window */
    gtk_container_add (GTK_CONTAINER (window), button);
   
 /* show the widgets */
    gtk_widget_show (button);
    gtk_widget_show (window);
  
    gtk_main ();
   
    return 0;
}

假设文件保存为: hello.c
然后编译: gcc -o hello hello.c `pkg-config --cflags --libs gtk+-2.0`
(关于这个奇怪的gcc编译选项,GTK+文档上有详细解释)
用: ./hello 运行就出现一个带有一个按钮的小窗口,如下图:

每个GTK+程序的框架都是差不多的。像我们这个程序,在main()函数中用gtk_init(&argc, &argv)初始化环境,然后定义一些控件让他们显示,最后用gtk_main()进入主循环,等待各种事件的发生(了解Windows程序设计的朋友会感觉这和Windows GUI编程模式差不多:)。这里最重要的地方就是把各种事件通过回调函数(callback function)和控件联系起来,使控件在某事件发生时(比如鼠标点击)产生某种响应。

什么是“回调函数”呢?在上面的程序中,void hello()函数就是一个回调函数。通过g_signal_connect()这个信号连接函数使之与button连接,在button被点击(clicked)时就触发hello()函数的运行(各种不同的GUI构建工具其基本原理都是这样的)。下面让我们来看看这个奇妙的信号连接函数是如何工作的:


这是第一种信号连接函数的原型声明:

gulong g_signal_connect( gpointer      *object, //发出信号的控件
                         const gchar   *name,  //信号名称
                         GCallback     func,  //回调函数(对信号要采取的动作)
                         gpointer      data ); //传给回调函数的数据

它对应的回调函数是:

void func( GtkWidget *widget,  //发出信号的控件
                    gpointer   callback_data ); //穿过来的数据

表示object这个控件在接收到name信号以后调用func函数。比如上面的例子:
g_signal_connect (G_OBJECT (button), "clicked",
        G_CALLBACK (hello), NULL);

就是指button这个控件在接收鼠标点击这个动作时,就发出”clicked"这个事件,我们捕获这个事件后调用hello()这个回调函数。然后hello()函数里面第一个参数widget现在就是button,第二个参数data为NULL(从g_signal_connect()传过来的)。值得注意的是在GTK+中信号是用字符串形式表示的(比如这里的“clicked”)。

现在我们应该了解了GTK+程序的工作原理了,再复杂的Gnome程序其基本原理就是上面我们分析的信号捕捉=>函数回调 。还有一种信号连接函数是这样的:               

gulong g_signal_connect_swapped( gpointer     *object,  //发出信号的控件
                                 const gchar  *name,  //信号名称
                                 GCallback    func,   //回调函数
                                 gpointer     *widget ); //传给回调函数的数据

它和g_signal_connect()作用相同,不同的只是它的回调函数只接收一个参数,它对应的回调函数是:                  

void callback_func( GtkObject *object );

这对于调用GTK+自带的一些只接收一个参数的函数(比如gtk_widget_destroy)来说是十分必要的,比如我们想让鼠标点击按钮时让窗口关闭,就可以加这样一个信号连接函数:

g_signal_connect_swapped (G_OBJECT (button), "clicked",  //让鼠标发出"clicked"事件
         G_CALLBACK (gtk_widget_destroy),       //调用系统函数使窗口关闭
                              G_OBJECT (window));       //把window作为参数传给gtk_widget_destroy()


信号连接函数不仅可以和控件产生的信号进行连接,而且可以和特殊的X-windows”事件“进行连接。我们知道,Gnome/KDE之类的窗口管理程序自己可以产生一些事件(比如按Alt+F4会产生一个窗口关闭事件)。所以GTK也允许我们用g_signal_connect()使我们的程序对窗口管理器产生的事件作出正确的反应。下面是一些常见的X-windows事件:
button_press_event
button_release_event
scroll_event
delete_event

这些事件的意思一目了然,就像GTK各函数的意思一样(比如gtk_main_quit肯定是退出程序了:)
只是对事件作出反应的回调函数和前面的有点不同:
static gint callback_func( GtkWidget *widget,  //接收事件的控件
                    GdkEvent  *event,    //事件名称
                    gpointer   callback_data );  //传给回调函数的数据

这个函数的返回值为TRUE或FALSE,返回TRUE的时候表示GTK程序已经完成事件处理,窗口管理器不用再触发下面的事件,返回FALSE时继续调用后续函数。再GTK文档上有一个窗口管理器发出delete_event事件的例子,当callback函数返回TRUE时程序不再调用destroy事件,而返回FALSE时程序继续调用destroy事件使得程序退出。

好的,我们关于信号和事件处理部分已经讲玩了。但是我们只是一个劲地往程序里加事件,有没有方法使得我们能够去掉连在控件上的信号,事件呢?答案是肯定的。

注意g_signal_connect()函数的返回值gulong,还有许多比如gint, gchar等,这是GTK+对ANSI C数据类型的包装,使得GTK的移植性更好。这里gulong表示g_signal_connect()返回了一个信号ID,用来代表这个事件信号。我们可以利用这个ID来去掉控件上这个事件,这是去掉信号连接的函数原型:

void g_signal_handler_disconnect( gpointer object, //信号和哪个控件有一腿:)
                                  gulong   id );  //信号的ID

在GTK+的API里面还有一些事件,信号方面的函数,比如:
/* 暂停信号处理 */
void g_signal_handler_block( gpointer object,
                             gulong   id );
/* 重新进行信号处理 */
void g_signal_handler_unblock( gpointer object,
                               gulong   id );
如果你对这个有兴趣研究,可以参阅GTK的API文档,里面有简介明了的介绍。

OK! 终于完成了我们Linux GUI编程的第一课了:) 下一次让我们来学习一下如果在GTK窗口上摆放控件。

                                                --------2004-7-28


[C语言系列]C# 和 Linux 时间戳转换  [Web开发]PHP flock文件锁介绍
[Web开发]flock() Linux下的文件锁  [电脑应用]Linux下的六个免费的虚拟主机管理系统介绍
[电脑应用]Linux数据库大比拚  [操作系统]在Windows中玩转Linux操作系统
[办公软件]在RedHat Linux 9里安装gaim0.80  [办公软件]掌握 Linux 调试技术
[办公软件]理解 Linux 配置文件  [聊天工具]Real10 & Xpdf installation on Linux Box
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · Sql Server  · MySql
    · Access  · ORACLE
    · SyBase  · 其他
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台