Licence Informatique 1 - GTK : Callbacks avec arguments
Table of Contents
1 Callbacks avec arguments
1.1 Documentation
Pour le moment on a utilisé des fonctions de callback ayant la signature suivante :
void fonction_de_callback();
C'est-à-dire qu'elles ne prenaient aucun paramètre et ne retournaient aucune valeur.
Cependant, on peut voir dans la documentation de GTK que ce n'est pas la seule signature acceptable. Par exemple, regardons la documentation des objets de type GtkEntry (http://developer.gnome.org/gtk2/2.24/GtkEntry.html). Dans la section Signals, on peut cliquer entre autres sur "delete-from-cursor", ce qui mène à la page http://developer.gnome.org/gtk2/2.24/GtkEntry.html#GtkEntry-delete-from-cursor. On peut alors lire l'encadré suivant :
void user_function(GtkEntry *entry, GtkDeleteType type, gint count, gpointer user_data);
C'est la signature que peut avoir une fonction de callback associée au signal "delete-from-cursor". Lorsque votre fonction sera appelée par GTK, elle recevra 4 arguments que vous pouvez utiliser dans sa définition.
1.2 Signature la plus courante des fonctions de callback
La plupart du temps, les signaux GTK sont associés à la signature suivante, qu'on trouve par exemple pour le signal "clicked" de GtkButton (http://developer.gnome.org/gtk2/2.24/GtkButton.html#GtkButton-clicked).
void user_function ( GtkWidget *pWidget, gpointer user_data);
- type de retour : void (pas de retour)
- premier argument : GtkWidget* pWidget
pWidget désigne l’objet qui a lancé le signal : lorsque la fonction callback est appelée par la boucle infinie, celle-ci lui passe l’objet émetteur du signal en paramètre. Par exemple, supposons que l'on ait deux boutons B1 et B2 et que l'on veuille désactiver chaque bouton dès que l'utilisateur a cliqué dessus. Il n'est pas nécessaire d'écrire deux fonctions de callback différentes pour réaliser cela. A la place, on peut utiliser la fonction suivante :
void desactivation(GtkWidget *pWidget, gpointer user_data) { gtk_widget_set_sensitive( pWidget, FALSE ); }
Cette même fonction peut être associée aux signaux clicked des deux boutons :
gtk_signal_connect( B1, "clicked", desactivation, NULL); gtk_signal_connect( B2, "clicked", desactivation, NULL);
- second argument : gpointer pData
Il s’agit d’un pointeur générique (gpointer en Glib est l’équivalent de void* en C) qui peut contenir tout et n’importe quoi (tout ce qu’on aura besoin de passer en argument à la fonction de callback). L'argument pData prend la valeur passée en dernier argument lors de l'appel à
gtk_signal_connect
.Par exemple, imaginons une fenêtre qui contient un bouton B et un label L ; si l’action sur le bouton B doit modifier le libellé du label L, pour mettre à jour le libellé de L à la suite de l’événement “cliquer B”, il faut que la fonction callback associée à “cliquer B” ait connaissance du label L dont le libellé doit être modifié. Appelons changerLabel cette fonction de callback : on passera alors le label L en argument de changerLabel, et ce passage est indiqué au moment de l’attachement par
gtk_signal_connect
de la fonction changerLabel au signal “clicked” de l’objet B :gtk_signal_connect(GTK_OBJECT(B), "clicked", G_CALLBACK(changerLabel), L);
En effet, l’instruction :
gtk_signal_connect(GTK_OBJECT(pObjet), strSignal, G_CALLBACK(nomFonction), pData)
a exactement l’effet suivant : lorsque l’objet pObjet émet le signal strSignal, la boucle événementielle appelle la fonction nomFonction avec les arguments pObjet et pData ; autrement dit, elle exécute l’instruction
nomFonction(pObjet, pData);
(dans notre exemple : “ changerLabel(B,L); ”)