GTK中的机制

 

GTK中的信号机制

一、            为了方便用户使用,定义了如下的宏

/* --- 便于使用的宏定义*/

#define g_signal_connect(instance, detailed_signal, c_handler, data) /

    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)

#define g_signal_connect_after(instance, detailed_signal, c_handler, data) /

    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_AFTER)

#define g_signal_connect_swapped(instance, detailed_signal, c_handler, data) /

    g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, G_CONNECT_SWAPPED)

#define          g_signal_handlers_disconnect_by_func(instance, func, data)                                                                 /

    g_signal_handlers_disconnect_matched ((instance),                                                                                     /

                                                            (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), /

                                                            0, 0, NULL, (func), (data))

#define          g_signal_handlers_block_by_func(instance, func, data)                                                                           /

    g_signal_handlers_block_matched      ((instance),                                                                                    /

                                                         (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),        /

                                                         0, 0, NULL, (func), (data))

#define          g_signal_handlers_unblock_by_func(instance, func, data)                                                                       /

    g_signal_handlers_unblock_matched    ((instance),                                                                                    /

                                                         (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA),        /

                                                         0, 0, NULL, (func), (data))

二、 /* 信号连接实现函数*/

gulong

g_signal_connect_data (gpointer       instance,//发送信号的对象

                     const gchar   *detailed_signal,//信号名称

                     GCallback      c_handler,//回调函数

                     gpointer       data,//传递给回调函数的参数

                     GClosureNotify destroy_data,//销毁数据的函数

                     GConnectFlags  connect_flags)//信号连接的选项

{

       (1)/****************为了安全起见,做如下检查******************/

     //检查发送信号的对象是否存在

     g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);

     //检查发送的信号是否存在

     g_return_val_if_fail (detailed_signal != NULL, 0);

     //检查回调函数是否存在

     g_return_val_if_fail (c_handler != NULL, 0);

       (2)//根据信号名称获取信号id

     signal_id = signal_parse_name (detailed_signal, itype, &detail, TRUE);

       (3)//根据信号id 获取信号节点

      SignalNode *node = LOOKUP_SIGNAL_NODE (signal_id);

       (4)//根据信号节点判断信号的有效性

      if (detail && !(node->flags & G_SIGNAL_DETAILED))

       g_warning ("%s: signal `%s' does not support details", G_STRLOC, detailed_signal);

      else if (!g_type_is_a (itype, node->itype))

       g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);

      else

       {

         (5)//生成信号处理器

         Handler *handler = handler_new (after);

 

         //信号处理器 序号

         handler_seq_no = handler->sequential_number;

         handler->detail = detail;

         //信号处理函数

         handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));

         g_closure_sink (handler->closure);

         (6)//根据信号id,发出信号的对象,信号处理器插入到信号处理器列表中

         handler_insert (signal_id, instance, handler);

}

三、            信号的触发(信号处理器的执行)

       gtk_main()进入事件循环,生成GMainLoop对象,

       由GMainLoop管理GMainContext对象,而GMainContext则管理则所有的事件源!

       当相应的事件发生时候,查找信号处理器列表,然后执行。

 

 

 

/*******************************************************************************************************************/

GTK+ 的面向对象机制
作者: 刘鹏
日期: 2008-11-20
GTK+ 虽然是用 C 语言开发,但它使用了面向对象的设计思想,并通过一些技巧实现了面向对象中的封装、继承和多态。
简介

面向对象编程语言 (如 C++、Java) 把数据和对数据的操作封装在一起构成类,由类来产生对象,由对象来构建程序。通过继承、重载、多态等机制大大增强软件的可重用性和可维护性。C语言虽然不是面向对象语言,但GTK+以及建立在其上的GNOME库却使C语言模拟出了一些典型的面向对象机制,如封装、继承和多态。本文详细介绍了它们的实现方法。

结构、函数指针与类

对象的一个重要特性是将数据和对数据的操作封装在一起,受保护的私有数据只能通过成员函数才能访问和修改。GTK+ 使用 C 语言的结构体来模拟对象。一个结构体就可以看成一个类,结构体里的数据成员就是类的成员变量,结构体里的函数指针变量就是类的成员函数。用这个结构体定义的一个变量可以看成一个对象。这样类和对象就基本实现了。

举个例子,下面的结构 GTKObjectClass 就可以看成一个类,其中 flag 是成员变量,三个函数指针是成员函数。

struct _GtkObjectClass
{
    guint32 flag;

    void (*set_arg) (GtkObject *object, GtkArg *arg, guint arg_id);
    void (*get_arg) (GtkObject *object, GtkArg *arg, guint arg_id);
    void (*destroy) (GtkObject *object);
};
结构体成员与继承

有了对象作为基础,通过在对象中加入新的数据和对这些数据进行操作的函数,就实现了继承。被继承的类称为父类或基类,由基础类派生出来的类称为子类或派生类。子类继承了父类的数据和对这些数据进行操作的成员函数,并加入了新的数据和成员函数,实现了对原有父类的重用和扩展,从而实现了可重用性和可扩展性。

之前提到,我们用 C 语言的结构当作面向对象中的类,子类继承了父类的成员变量和成员函数,那么,我们让每一个子类所在的结构体都包含一个父类的结构体,子类结构体的第一个成员是其父类结构体,那么子类就继承了父类的成员,由此就实现了继承。

举个例子,GTK+ 中有一个类 GtkObject,它是所有其他类的父类。GTK+ 中最常用的按钮控件也是一个类 GtkButton,它继承自 GtkObject。它与 GtkObject 的继承关系是:

GtkObject->GtkWidget->GtkContainer->GtkBin->GtkButton

它们在 GTK+ 的实现如下所示:

struct GtkObject {
    ......
}

struct Widget {
    GtkObject object;
    ......
}

struct GtkContainer {

    GtkWidget widget;
    ......
};

struct GtkBin {

    GtkContainer container;
    ......
};

struct GtkButton {
    GtkBin bin;
    ......
};

强制类型转换与多态性

多态性,用一个经典的英文解释就是 a value can belong to multiple types,即一个值属于多种类型。在面向对象语言语言中,一个对象可能属于一个子类,同时也属于该子类的父类,如,在 C++ 中经常用到这样的定义:

ParentClass A = new ChildClass ();

对象 A 既属于子类,也属于父类。

在 C 语言中,可以使用指针的强制类项转换来实现多态性,,但要求父类结构体数据必须位于子类结构体的开始。比如,对于一个GtkButton 类型的button控件变量 (它其实是一个指向 GtkButton 结构体的指针),通过宏 GTKBIN(button) 就得到了其父类 ( GTK+ 预定义的宏 GTKBIN 其实是进行了强制类型转换,把一个 GtkButton 类型的指针强制转化为 GtkBin 类型的指针)。

以创建一个 Button Widget 为例,如下所示:

GtkWidget *button;
button =  gtk_button_new_with_label ("Hello World");
g_signal_connect (G_OBJECT (button), "clicked",
              G_CALLBACK (hello), NULL);

button 声明为 GtkWidget 类型的指针,用 gtk_button_new_with_lable 创建一个 GtkButton;G_OBJECT 是一个宏,完成强制类型转换,这里将 button 从 GtkWidget 类型转换成 GObject 类型。

Reference

http://book.csdn.net/bookfiles/645/10064520529.shtml

 

/*********************************************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值