Aller au menu - Aller au contenu

Icône Gestion des évènements : les signaux

Avatar
Avatar
Avatar
Avatar
Mise à jour : 12/07/2009
1 945 visites depuis 7 jours, dont 116 sur ce chapitre classé 71/786
Nous allons maintenant voir comment intercepter les actions de l'utilisateur et agir en conséquence. Au programme, explications, exemples et exercices.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Comment ça marche ?

Nous allons traiter ici ce qu'on appelle la programmation évènementielle ! Cela consiste à intercepter les actions de l'utilisateur pour les traiter : clic sur un bouton, validation d'une zone de texte, etc.. Sans ça, votre programme ne fera rien ! En fait, c'est cette gestion qui fera le "gros" du programme, tous se passe dedans !


Principe



Vos programmes ne suivront désormais plus du tout le même plan. Je m'explique : :)

  • Avant, vos programmes étaient dis linéaires : votre code s'exécutait dans l'ordre où vous l'aviez écrit (du haut vers le bas), vous étiez d'ailleurs assez limités par cette contrainte. De plus, l'utilisateur n'avait aucune liberté, il ne pouvait rien faire d'autre que ce que vous lui proposiez.
  • Maintenant, c'est une toute autre façon de penser. Dans votre programme, vous définissez votre interface, les boutons et tout ça, on lance le tout, puis on passe la main à l'utilisateur. C'est lui qui choisi ce qu'il fait, quand, et comment.


Cette méthode de programmation est dite évènementielle, elle suit le principe action -> réaction.

Le principe est vraiment simple : lorsqu'un évènement a lieu avec un widget, celui ci émet ce qu'on appelle un signal (celui-ci sera différent pour chaque action que le widget gère), l'objectif du jour est de savoir faire réagir notre application à la réception de ces signaux.
GTK s'occupe de tout, donc la partie technique ne nous regarde pas; cependant il faut bien comprendre comment ça fonctionne.

Il n'y a qu'une seule chose à faire. On va utiliser une fonction qui dira à GTK :
  • De quel widget on veut traiter un évènement.
  • Le signal (l'évènement) que l'on veut traiter.
  • Le nom d'une fonction (faite par vous), à appeler lorsque cet évènement survient. Ce type de fonction est appelé fonction callback.

En gros, on peut résumer avec un petit schéma :
ACTION UTILISATEUR
|
ÉMISSION SIGNAL
|
RÉCEPTION SIGNAL
|
FONCTION CALLBACK


Passons maintenant à la pratique ! Voilà le code de base sur lequel nous allons travailler. Créez un projet et collez ce code dedans :

Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdlib.h>
#include <gtk/gtk.h>

void mafonction(GtkWidget *widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc, char **argv)
{
    /* Variables */
    GtkWidget * MainWindow = NULL;

    /* Initialisation de GTK+ */
    gtk_init(&argc, &argv);

    /* Création de la fenêtre */
    MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(G_OBJECT(MainWindow), "delete-event", G_CALLBACK( mafonction ), NULL);

    /* Affichage et boucle événementielle */
    gtk_widget_show(MainWindow);
    gtk_main();

    /* Fermeture de GTK+ */
    gtk_exit(EXIT_SUCCESS);
    return EXIT_SUCCESS;
}


Observons ce code, et essayons de le comprendre. La seule nouveauté est la petite fonction en haut, normalement vous devriez vous dire :

À quoi sert-elle ?
Quand est-elle appelée ? Comment ?
Qu'est-ce qu'on doit mettre dedans ? Etc ..
À quoi sert la fonction g_signal_connect au milieu du code ?

Autant de questions auxquelles je vais tenter de répondre.


Gérer une action



Penchons-nous déjà sur cette ligne :

Code : C
1
g_signal_connect(G_OBJECT(MainWindow), "delete-event", G_CALLBACK( mafonction ), NULL);


L'appel de cette fonction permet de gérer un évènement. Voyons les paramètres :
  • MainWindow : Ce premier paramètre doit être le widget dont on veut gérer un évènement, en le mettant dans la macro G_OBJECT.
    Ici, on gère un évènement de la fenêtre.
  • "delete-event" : On écrit le nom du signal que l'on souhaite intercepter dans une chaine de caractères. Il existe un nom de signal pour chaque signal existant. En l'occurrence, "delete-event" est émis lorsque on clique sur la croix d'une fenêtre.
  • mafonction : Il faut mettre ici le nom d'une fonction callback qui sera appelée lors de l'évènement, en le mettant dans la macro G_CALLBACK.
  • NULL : Pour finir, on donne un paramètre passé automatiquement à la fonction donnée juste avant. On s'en sert pour passer des données à la fonction. Ici, on met NULL.

Sachant que le prototype est :

Code : C
1
gulong g_signal_connect(gpointer *object, const gchar *name, GCallback func, gpointer func_data );


On peut dire que : Quand object émet le signal name, GTK+ appelle la fonction func avec les paramètres object et data. Donc à ce moment là, GTK génère cet appel et l'exécute :

Code : C
1
func(object, data);


La fonction en question devra toujours avoir le prototype suivant :

Code : C
1
void mafonction(GtkWidget *widget, gpointer data);


En fait, ce prototype pourra changer pour certains évènements, mais ce sont des cas particuliers. Nous en parlerons en temps voulu.

Ainsi, on a accès au widget qui à émis le signal par le premier paramètre, et à une donnée quelconque par le deuxième.
Maintenant, reprenez votre code, vous êtes maintenant en mesure de le comprendre : le programme est quitté lorsqu'on clique sur la croix de la fenêtre.


La boucle principale



Pour gérer les évènements, GTK+ utilise une boucle évènementielle. C'est une boucle infinie (enfin presque, faut bien qu'on puisse quitter) dans laquelle GTK+ s'occupe d'émettre les signaux, et d'appeler les fonctions callback nécessaires.
Pour lancer cette boucle (le plus souvent, pour "lancer le programme" en quelque sorte), on appelle la fonction gtk_main :

Code : C
1
void gtk_main(void);


Pour quitter cette boucle, la fonction est :

Code : C
1
void gtk_main_quit(void);


Vous savez maintenant tout ce qu'il faut savoir pour bien aborder la gestion des évènements. Assurez-vous d'avoir bien compris, je vous conseille de relire l chapitre plusieurs fois si besoin. Je sais que tout cela peut vous paraitre un peu flou, mais après tout c'est quand même plus simple que les pointeurs ! :p (à moins que..?)

Exercices

Maintenant que vous avez (plus ou moins) compris comment on traitait les événements, voilà deux exercices. Il serait vraiment essentiel de les réussir, et pour vous y aider je ne donne pas de solution : l'important, c'est que ca marche !
Pour bien commencer, prenez le code de la partie précédente. N'oubliez pas que tout se passe dans la fonction qui est en haut ! ;)

Exercice 1



Faites un programme qui fait ceci lorsque on clique sur la croix :
  • Ecrire le titre de la fenêtre dans la console, en inversant l'ordre des lettres ! :p
  • Quitter le programme.
Assez facile, pensez à activer la console si elle n'apparait pas ! (Projet > Options)


Exercice 2



Pas beaucoup plus dur, mais plus marrant ! ;)
  • Ecrivez un programme qui ouvre une deuxième fenêtre quand on clique sur la croix de la première.
  • Quitter le programme quand on clique sur la croix de la deuxième.
  • La deuxième fenêtre contiendra le titre de la première dans un label.
Attention, ici on a deux signaux à gérer, un pour chaque fenêtre !


Exercice 3



Vous devriez y arriver, mais il est plus difficile.
  • Créez une fenêtre, avec la première lettre de votre prénom dedans (dans un label).
  • Quand on clique sur la croix de la fenêtre, on change la lettre affichée par la suivante.
  • Quand on est arrivé à la fin du nom, on quitte.

Q.C.M.

Comment appelle on le type de programmation utilisé lorsqu'on programme avec GTK+ ?
Quelle fonction permet de lancer la boucle évènementielle ?
Et quelle fonction permet de quitter cette boucle ?

Statistiques de réponses au QCM

Voilà enfin cette première partie sur GTK+ terminée, vous avez normalement acquis les bases et êtes prêts à faire des choses plus intéressantes ! Au programme de la seconde partie : du concret ! Découvertes des widgets les plus utilisés, au moins un TP, bref : de quoi vous occuper. :)
Chapitre précédent Sommaire Chapitre suivant

Partager

25 commentaires pour "Gestion des évènements : les signaux"
Note moyenne : 3.14 / 4 (29 votes)
Pseudo Commentaire
Hors ligne Dagrut # Posté le 14/10/2007 à 21:06:04
BLACK OUT
Avatar

Super tuto, comme d'habitude. Ça en deviens lassant!! Hé, non, ne partez pas! ^^

Juste une petite question : c'est possible de faire l'exercice 3 dans variable globale? moi j'ai pas réussi à m'en séparer.
 
Hors ligne Link/DD # Posté le 03/09/2008 à 17:35:34
Avatar
Flux RSS

Salut,
Bon tuto, bien expliqué pour un débutant.

Sachant déjà programmé avec la librairie GTK+ depuis assez longtemps je ne lirai ce tuto que par curiosité.

Mais il me semble que l'event delete-event est déprécié non ? Il faudrait utiliser destroy.

Cream-Browser : Navigateur internet GTK+/WebKit au look vimesque
GreenPKG : Gestionnaire de paquet basique (bdd SQLite / paquet source / gestion d'un unique dépot)
SlightX : Système d'exploitation conforme POSIX pour architecture x86 (en pause pour le développement de Cream-Browser)
PCStats : Affiche les infos CPU, RAM, disque, net, etc... (compatible uniquement GNU/Linux : utilisation de sysctl et /proc)
 
Hors ligne softdounia # Posté le 21/03/2009 à 23:36:23
A
Avatar

Ville : Alger
Pays : Algérie
Études : ETS Montréal

super Tuto :magicien:

Mais j'attente la suite comme même, elle manque beaucoup :pirate: (la suite, la suite, la suite)

Pour la notr un 16/20.

Les 40e rugissants et les 50e hurlants. o_O --> Brainstorming --> CamelCase
Image utilisateur

-------------
"je crois qu'on ne peut mieux vivre qu'en chercant à devenir meilleur, ni plus agréablement qu'en ayant pleine conscience de son amélioration"
Socrate >_<
-------------
les meilleurs peintres se sont fait dire qu’ils n’étaient pas bon, aujourd’hui ce sont des Dieux!
-------------
RTFM :-° l'expression anglaise d'argot Internet Read the fucking manual (« Lis le foutu manuel ») ;
-------------
Mon CV en ligne ici
 
Hors ligne chahaman # Posté le 03/07/2009 à 02:02:33
Avatar

ce tuto est le dernier et le plus aportant,
finalement la suite je l'aprendré sur les autre site
entou k merci pour ces tutos ils m'ederont a comprendre la suite dans d'autre site tutoriel.
Hors ligne ndac++ # Posté le 10/01/2010 à 17:00:10

Avatar

Avis : Bon

Excellent boulot
rien a dire
seulement qu'on attend la suite et un peu plus de précision
je vous en supplie ne baissaient pas les bras surtout avec le bon début
note
Secret (cliquez pour afficher)
19,75 (rien que pour la suite -0,25)

un concerné n'est pas obligatoirement un imbécile encerclé
 

Voir tous les commentaires