GObject 自定义signal信号和回调函数

相关参考:

http://library.gnome.org/devel/gobject/2.14/signal.html

nautilus-2.30.0/src/file-manager/fm-directory-view.c

在GObject 中(通常是GTK中)我们需要定义一些自己的信号,用来实现控件之间callback(回调函数)的触发。

例如:有两个控件Sender 和 Receiver, 我们需要接收 Sender 中发射的一个 ”something_changed“ 信号。假定这个信号包含一个参数(MyParam *param)。那么。通常的用法是:

        g_signal_connect (sender, "something_changed",
                          G_CALLBACK (receiver_callback), param);

第一步,先为信号生成一个参数转换函数:

[socol@localhost ~]$:cat marshal.list
VOID:OBJECT

[socol@localhost ~]$:glib-genmarshal --header --prefix=custom_marshal marshal.list > custom_marshal.h
[socol@localhost ~]$:glib-genmarshal --header --prefix=custom_marshal marshal.list > custom_marshal.c
 

然后,在Sender.h中声明这个信号:

struct SenderClass {
        GObject parent_class;

        void    (* something_changed)                (Sender *sender, MyParam *param);
... ...
}
 

最后,在Sender.c中定义和发射这个信号:

enum {
        SOMETHING_CHANGED,
        LAST_SIGNAL
};

static guint signals[LAST_SIGNAL];


static void
sender_class_init (SenderClass *klass)
{

        signals[SOMETHING_CHANGED] =
                g_signal_new ("something_changed",
                              G_TYPE_FROM_CLASS (klass),
                              G_SIGNAL_RUN_LAST,
                              G_STRUCT_OFFSET (SenderClass, something_changed),
                              NULL, NULL,
                              custom_marshal_VOID__OBJECT,  // 这里用到了上面生成的marshal,
                                                                                               // GLIB中本身也提供了一系列的marshal来调用。
                                                                                               // 我们可以用g_cclosure_marshal_VOID__OBJECT来替换
                              G_TYPE_NONE, 1, MY_PARAM_TYPE);
}


void
sender_make_something_changed (Sender *sender, MyParam *param)
{
        g_signal_emit (sender, signals[SOMETHING_CHANGED], 0, param);
}
 

另外,关于对象中属性的变化,也可以使用类似"notify::xxxchanged"的信号来关联回调。如下所述:

Signal Details

The "notify" signal

void                user_function                      (GObject    *gobject,
                                                        GParamSpec *pspec,
                                                        gpointer    user_data)      : Run First / No Recursion / Has Details / Action / No Hooks
The notify signal is emitted on an object when one of its properties has been changed. Note that getting this signal doesn't guarantee that the value of the property has actually changed, it may also be emitted when the setter for the property is called to reinstate the previous value.

This signal is typically used to obtain change notification for a single property, by specifying the property name as a detail in the g_signal_connect() call, like this:

g_signal_connect (text_view->buffer, "notify::paste-target-list ",
                  G_CALLBACK (gtk_text_view_target_list_notify),
                  text_view)
It is important to note that you must use canonical parameter names as detail strings for the notify signal.

gobject :

the object which received the signal.
pspec :

the GParamSpec of the property which changed.
user_data :

user data set when the signal handler was connected.

猜你喜欢

转载自socol.iteye.com/blog/903815