GObject对象系统(9) 创建和使用信号



How to create and use signals

Simple use of signals

The signal system in GType is pretty complex and flexible: it is possible for its users to connect at runtime any number of callbacks (implemented in any language for which a binding exists) [8] to any signal and to stop the emission of any signal at any state of the signal emission process. This flexibility makes it possible to use GSignal for much more than just emitting signals to multiple clients.

在GType中的信号系统是十分复杂和灵活的:它可以让它的用户在运行时连接任意数量的回调(如果绑定存在则回调可以用任意语言实现)到任意信号,并在信号发射的任意流程中停止信号的发射。这种灵活性使得GSignal的功能不仅限于给多个客户发送信号。

 

Simple use of signals 信号的简单使用

The most basic use of signals is to implement event notification. For example, given a ViewerFile object with a write method, a signal could be emitted whenever the file is changed using that method. The code below shows how the user can connect a callback to the "changed" signal.

信号的最基本用法是实现事件通知。例如,给定一个拥有write方法的ViewerFile对象,通过该方法可以在文件发生改变的时候发射一个信号。

下述代码展示了用户怎么连接一个回调到“changed”信号上。

1
2
3
4
5
file = g_object_new (VIEWER_FILE_TYPE, NULL);

g_signal_connect (file, "changed", (GCallback) changed_event, NULL);

viewer_file_write (file, buffer, strlen (buffer));

The ViewerFile signal is registered in the class_init function:

ViewerFile信号在class_init函数中注册。

1
2
3
4
5
6
7
8
9
10
11
file_signals[CHANGED] = 
  g_signal_newv ("changed",
                 G_TYPE_FROM_CLASS (object_class),
                 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
                 NULL /* closure */,
                 NULL /* accumulator */,
                 NULL /* accumulator data */,
                 NULL /* C marshaller */,
                 G_TYPE_NONE /* return_type */,
                 0     /* n_params */,
                 NULL  /* param_types */);

and the signal is emitted in viewer_file_write:

信号在viewer_file_write函数中被发射:

1
2
3
4
5
6
7
8
9
10
11
12
13
void
viewer_file_write (ViewerFile   *self,
                   const guint8 *buffer,
                   gsize         size)
{
  g_return_if_fail (VIEWER_IS_FILE (self));
  g_return_if_fail (buffer != NULL || size == 0);

  /* First write data. */

  /* Then, notify user of data written. */
  g_signal_emit (self, file_signals[CHANGED], 0 /* details */);
}

As shown above, the details parameter can safely be set to zero if no detail needs to be conveyed. For a discussion of what it can be used for, see the section called “The detail argument”。

上述中,如果没有detail需要传送的话detail参数可以安全地设置为0。

 

The C signal marshaller should always be NULL, in which case the best marshaller for the given closure type will be chosen by GLib. This may be an internal marshaller specific to the closure type, or g_cclosure_marshal_generic, which implements generic conversion of arrays of parameters to C callback invocations. GLib used to require the user to write or generate a type-specific marshaller and pass that, but that has been deprecated in favour of automatic selection of marshallers.

C信号的调用器总是应该设置为NULL,这样将有GLib选择给定信号的最适合的调用器,该调用器可能是与闭包相关的内部调用器,或者是实现了参数数组对C回调调用的通用转换的g_cclosure_marshal_generic调用器。GLib曾经要求用户编写或者提供一个类型相关的调用器并将该调用器传递给信号注册函数,但这已经不被支持而是鼓励闭包调用器的自动选择。

 

Note that g_cclosure_marshal_generic is slower than non-generic marshallers, so should be avoided for performance critical code. However, performance critical code should rarely be using signals anyway, as emitting a signal blocks on emitting it to all listeners, which has potentially unbounded cost.

注意g_cclosure_marshal_generic比非通用的调用器要更慢,所以应该在有性能要求的代码中避免使用。但是性能敏感代码很少使用信号,因为信号发射时会发射到它的所有监听者,造成阻塞,这可能造成很大的性能损耗。

 

[8] A Python callback can be connected to any signal on any C-based GObject, and vice versa, assuming that the Python object inherits from GObject.

注8: 一个Python回调可以连接到任何C写的GObject的任何回调上,如果Python对象派生自GObject,则相反也可以。



 

转载于:https://my.oschina.net/wsgalaxy/blog/3008514

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值