2009-10-12 33 views
3

我想创建并发出GTK信号:创建并发出GTK信号

g_signal_new("child-finished", 
    G_TYPE_OBJECT, 
    G_SIGNAL_RUN_FIRST, 
    0, 
    NULL, NULL, 
    NULL,   // *** I think this is where I need to change it 
    G_TYPE_NONE, 0); 
g_signal_connect(G_OBJECT(myWindow), "child-finished", G_CALLBACK(MyCallback), NULL); 

这里是我的代码发出信号:

gtk_signal_emit_by_name(referenceToMyWindow, "child-finished"); 

这里是我的代码是处理信号:

void MyCallback(GtkWidget *w, GdkEvent *e) 
{ 
    // handler code here 
} 

当我运行代码,我得到了以下错误:

GLib-GObject-CRITICAL **: g _closure_ invoke: assertion `closure->marshal || closure->meta_marshal' failed

我知道它是与传递一个编组到g_signal_new功能,但我不知道编组是什么,我不明白the documentation,以及在线的例子是少之又少。我如何声明并连接自己的信号?

回答

3

GObject的库提供了一些builtin marshallers,所以你的代码也许应该是:

g_signal_new("child-finished", 
      G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST, 
      0, NULL, NULL, 
      g_cclosure_marshal_VOID__POINTER, 
      G_TYPE_NONE, 1, G_TYPE_POINTER); 

,或者,如果你想要的类型检查:

g_signal_new("child-finished", 
      G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST, 
      0, NULL, NULL, 
      g_cclosure_marshal_VOID__BOXED, 
      G_TYPE_NONE, 1, GDK_TYPE_EVENT); 

信号处理器的参数必须是目前(对象本身就是隐含的),所以一定要指定一个指针(如第一个例子)或者一个盒装类型(如第二个例子)。

如果你需要的编码器不在内置函数中,你可以使用glib-genmarshal工具或者直接对它进行编码(这很简单,只需检出glib-genmarshal的输出)。

+0

只是修正了上述内容:GBoxed类型没有类型检查,它们只是C结构的包装器,没有类型信息。 G_TYPE_POINTER与G_TYPE_BOXED之间的真正区别在于后者使用了GdkEvent结构的_copy_。如果事件没有被修改,这并没有什么区别,但是如果你需要修改它,使用G_TYPE_POINTER。 – ntd 2009-10-12 23:08:44