2009-10-12 4 views
3

Je suis en train de créer et émettre un signal GTK:créer et émettre le signal de 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); 

Voici mon code qui émet le signal:

gtk_signal_emit_by_name(referenceToMyWindow, "child-finished"); 

Et voici mon code qui gère la signal:

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

Quand je lance le code que je reçois l'erreur suivante:

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

Je sais qu'il a quelque chose à voir avec le passage d'un placier à la fonction g_signal_new, mais je ne sais pas ce qu'est un placier est, je ne peux pas comprendre the documentation, et les exemples sont en ligne peu nombreux. Comment puis-je déclarer et connecter mon propre signal?

Répondre

3

La bibliothèque GObject fournit quelques builtin marshallers, de sorte que votre code devrait probablement:

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); 

ou, si vous voulez la vérification de type:

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); 

Les paramètres du gestionnaire de signaux doit être présent (l'objet lui-même est implicite), assurez-vous donc de spécifier un pointeur (comme dans le premier exemple) ou un type encadré (comme dans le second exemple).

Si le marshaller dont vous avez besoin n'est pas présent dans les builtins, vous pouvez utiliser l'utilitaire glib-genmarshal ou le coder directement vous-même (il est assez trivial, il suffit de vérifier la sortie de glib-genmarshal).

+0

Juste une correction de ce qui a été dit plus haut: Les types GBoxed n'ont pas de contrôle de type, ils sont seulement des wrappers pour les structures C sans informations de type. La vraie différence entre G_TYPE_POINTER et G_TYPE_BOXED est que dans ce dernier, une copie de la structure GdkEvent est utilisée. Si l'événement n'est pas modifié, cela ne fait aucune différence, mais si vous avez besoin de le modifier, utilisez G_TYPE_POINTER. – ntd

Questions connexes