Licence Informatique 1 - GTK : Boîtes de dialogue et de message

Table of Contents

1 Filiation

GtkWindow → GtkDialog → GtkMessageDialog

2 Constitution

Une boîte de dialogue est une fenêtre préformatée constituée :

  • d'une zone de travail (GtkVBox) (on y place usuellement des labels et des zones de saisie) ;
  • d'une zone de boutons (GtkHBox) (les boutons peuvent être insérés au moment même de la création de la boîte ou plus tard, par utilisation d'une fonction spécifque) ;
  • d'une ligne de séparation (objet GtkHSeparator qui sépare la zone de travail et la zone des boutons).

Une boîte de message est une boîte de dialogue préformatée qui contient dans sa zone de travail un message (d'avertissement, d'information etc.). Ce message est défini à la création même de la boîte de message.

3 Vocation dans une IHM (Interface Homme-Machine)

Classiquement, une application est constituée d'une fenêtre principale avec un menu qui permet d'ouvrir d'autres fenêtres, chaque fenêtre correspondant à une fonctionnalité précise de l'application.

Ces fenêtres peuvent être des GtkDialog qui permettent à l'utilisateur d'atteindre ses buts (ex. : s'identifer auprès d'un système, paramétrer l'application, interroger une base de données etc.). De plus, lorsque l'utilisateur interagit avec l'application, celle-ci doit le tenir informé du bon usage qu'il doit faire du logiciel ainsi que de l'état de ses actions (ex. : message d'information en cas de saisie incomplète, message d'erreur en cas d'erreur logicielle, barre d'avancement d'une tâche en cours etc.) : c'est le rôle des boîtes de message.

4 Principales fonctions

  • création
    GtkWidget* gtk_dialog_new(void);
    
  • ajout d'un bouton
    GtkWidget* gtk_dialog_add_button(GtkDialog* pDialogue, 
                                     const gchar* libelle, 
                                     gint valRetour);
    

    ajoute un bouton de libellé libelle à la boîte de dialogue pDialogue.

    • le paramètre valRetour définit la valeur retournée par la boîte lorsque ce bouton est utilisé.
    • l'adresse renvoyée est celle du bouton qui vient d'être créé (utile si l'on veut agir sur le bouton après sa création)
  • lancement
    gint gtk_dialog_run(GtkDialog* pDialogue);
    

    lance la boîte de dialogue pDialogue (équivalent de la fonction gtk_main() pour une fenêtre principale); la valeur retournée (de type gint – ou int) est celle associée au bouton cliqué par l'utilisateur pour fermer la boîte de dialogue.

  • destruction
    void gtk_widget_destroy(GtkDialog* pDialogue);
    

    détruit la boîte de dialogue (… attention : toujours penser à détruire la boîte de dialogue pour libérer la mémoire !)

5 Manipulation

  • déclaration
    GtkWidget* pDialogue;
    
  • récupération de la GtkVBox d'une boîte de dialogue
    GtkWidget* pVBox = GTK_DIAlOG(pDialogue)->vbox;
    

    la GtkVBox récupérée ainsi dans pVBox représente la zone de travail de la boîte de dialogue

  • affichage
    gtk_widget_show_all(GTK_DIAlOG(pDialogue)->vbox);
    

    ou

    gtk_widget_show_all(pDialogue);
    

    permet d'afficher la zone de travail et tout ce qu'elle contient lors du lancement de la boîte par gtk_dialog_run().

6 En résumé

Pour modifier la zone de travail de la fenêtre, il faut :

  • accéder à la GtkVBox de la fenêtre (GTK_DIALOG(pDialogue)->vbox)
  • utiliser ensuite les méthodes habituelles des objets GtkVBox (gtk_box_pack_start(), … )

Pour travailler sur la zone de boutons de la fenêtre, il faut :

  • créer les boutons par les méthodes définies au niveau des objets GtkDialog (gtk_dialog_new_with_buttons(), gtk_dialog_add_button()).

Le cycle de vie d'une fenêtre :

  • affichage par appel préalable à gtk_widget_show_all(), sur la fenêtre elle-même ou sa zone de travail ;
  • lancement par gtk_dialog_run() ;
  • fin d'affichage après action de l'utilisateur sur la fenêtre : clic sur les boutons de la zone de boutons, fermeture de la fenêtre ;
  • destruction (libération de l'espace mémoire) par appel à gtk_widget_destroy().

7 Ajout d'un bouton

Pour ajouter un bouton avec la méthode gtk_dialog_add_button(), il faut spécifer le libellé (ou libellé avec raccourci clavier, ou image) du bouton (deuxième argument de la fonction), ainsi que la valeur retournée par le bouton (troisième argument de la fonction). Cette valeur peut être une valeur définie par le programmeur, ou une constante du type énuméré GtkResponseType. Pour revenir sur le libellé du bouton, on peut écrire directement la chaîne de caractéres souhaitée (ex. : "Quitter", "_Quitter"), ou l'identité d'une image en stock (ex. : GTK_STOCK_QUIT).

Exemple d'utilisation :

gtk_dialog_add_button(GTK_DIALOG(pDialogue), 
                      GTK_STOCK_CANCEL, 
                      GTK_RESPONSE_CANCEL);

8 Gestion événementielle de la boîte de dialogue

En principe, le programmeur ne gère pas les signaux émis par les boutons d'une boîte de dialogue. Lorsque l'on active la boîte de dialogue avec la fonction gtk_dialog_run(), celle-ci s'affiche, puis se fermera par action de l'utilisateur sur l'un de ses boutons ou sur la fenêtre (comportement par défaut : le programmeur peut aussi forcer la fermeture de la fenêtre dans le code). Si la fenêtre est fermée suite à un "clic" sur un bouton, c'est la valeur retournée par ce bouton qui sera renvoyée par la fonction gtk_dialog_run() (GTK_RESPONSE_CANCEL dans notre exemple). Si la fenêtre est fermée suite à un "clic" sur le coin N-E de celle-ci, c'est la valeur retournée par la fenêtre qui sera renvoyée (par défaut, la fenêtre renvoie alors la valeur GTK_RESPONSE_DELETE_EVENT).

9 Petit exemple récapitulatif

Cet exemple ouvre une boîte de dialogue, dont le titre est "Veux-tu dialoguer avec moi ?", et qui comporte un label "Cliquer sur le bouton de votre choix", ainsi que les deux boutons "Oui" et "Non".

void boiteDialogue()
{
  // Déclaration des objets
  GtkWidget* pDialogue = NULL;
  GtkWidget* plabel = NULL;
  GtkWidget* pVBox;
  guint reponse = GTK_RESPONSE_NONE;
  // Création des objets
  plabel = gtk_label_new("Cliquez sur le bouton de votre choix");
  pDialogue = gtk_dialog_new();
  // Apparence des objets
  // (En qualité d'héritier de GtkWindow, les GtkDialog peuvent utiliser les fonctions définies sur les GtkWindow)
  gtk_window_set_title(GTK_WINDOW(pDialogue), "Veux-tu dialoguer avec moi ?");
  gtk_window_set_default_size(GTK_WINDOW(pDialogue), 300, 100);
  // Spécifcation du contenu de la GtkDialog
  pVBox = (GTK_DIALOG(pDialogue))->vbox;
  gtk_box_pack_start(GTK_BOX(pVBox), plabel, FALSE, FALSE, 0);
  gtk_dialog_add_button(GTK_DIALOG(pDialogue), GTK_STOCK_YES, GTK_RESPONSE_YES);
  gtk_dialog_add_button(GTK_DIALOG(pDialogue), GTK_STOCK_NO, GTK_RESPONSE_NO);

  // Affichage des objets
  gtk_widget_show_all(pVBox);
  // lancement de la GtkDialog et gestion de sa valeur retour
  reponse = GTK_RESPONSE_YES;
  while (reponse == GTK_RESPONSE_YES)
    {
      reponse = gtk_dialog_run(GTK_DIALOG(pDialogue));
    }
  // Destruction de la GtkDialog
  gtk_widget_destroy(pDialogue);
}

Dans cet exemple, on lance autant de fois la boîte de dialogue que l'utilisateur clique sur le bouton "Oui". En revanche, dès qu'il ferme la fenêtre (gtk_dialog_run() renvoie alors la valeur GTK_RESPONSE_DELETE_EVENT) ou qu'il clique sur le bouton "Non" (gtk_dialog_run() renvoie alors la valeur GTK_RESPONSE_NO), la variable reponse contient alors une valeur différente de GTK_RESPONSE_YES et la boîte n'est pas relancée (condition d'arrêt de la boucle "while").

10 Boîtes de message

Une boîte de message est un cas particulier de boîte de dialogue, qui est destinée à délivrer un simple message à l'utilisateur.

Pour créer une boîte de message, on utilise la fonction suivante :

GtkWidget* gtk_message_dialog_new(GtkWindow* parent, 
                                  GtkDialogFlags flags, 
                                  GtkMessageType type,
                                  GtkButtonsType buttons, 
                                  const gchar* message);
  • GtkWindow* parent : fenêtre à partir de laquelle la GtkMessageDialog est lancée.

    Comme on lancera des fenêtres avec l'option GTK_DIALOG_MODAL, le paramètre parent peut être mis à NULL.

  • GtkDialogFlags flags : décrit le comportement de la GtkMessageDialog.

    Utiliser GTK_DIALOG_MODAL : on ne peut rien faire dans le reste de l'interface tant que la GtkMessageDialog est ouverte

  • GtkMessageType type : nature du message (alerte, erreur, information etc.). Le texte et l'icône correspondants seront affichés dans la barre de titre de la GtkMessageDialog.

    Valeurs possibles : GTK_MESSAGE_ { INFO, WARNING, QUESTION, ERROR}.

  • GtkButtonsType buttons : bouton ou combinaison de boutons à afficher dans la GtkMessageDialog.

    Valeurs possibles : GTK_BUTTONS_ {NONE, OK, CLOSE, CANCEL, YES_NO, OK_CANCEL}.

    Exemples : avec GTK_BUTTONS_NONE, la GtkMessageDialog ne comporte pas de bouton ; avec GTK_BUTTONS_OK_CANCEL, la GtkMessageDialog comporte deux boutons : "OK" et "Annuler".

  • const gchar* message : contenu du message à l'intention de l'utilisateur.

    Le message peut dépendre de variables (même syntaxe que printf ), Exemple :

    gtk_message_dialog_new(..., "i = %d", i);
    

Exemple d'utilisation : pour forcer l'utilisateur à répondre "Oui" sur la GtkDialog de l'exemple précédent, on peut ouvrir une boîte de message avertissant l'utilisateur qu'il doit répondre "Oui", tant qu'il répond "NON".

// Fonction de création de GtkMessageDialog à laquelle on passe en argument la fenêtre appelante
guint boiteMessage(GtkWidget* parent)
{
  // Déclaration des objets
  GtkWidget* pMessage = NULL;
  guint reponse = GTK_RESPONSE_NONE;
  // Création des objets
  pMessage = gtk_message_dialog_new(GTK_WINDOW(parent), 
                                    GTK_DIALOG_MODAL,
                                    GTK_MESSAGE_WARNING, 
                                    GTK_BUTTONS_OK, 
                                    "Vous devez dire Oui !");
  // lancement de la GtkMessageDialog
  reponse = gtk_dialog_run(GTK_DIALOG(pMessage));
  // Destruction de la GtkMessageDialog
  gtk_widget_destroy(pMessage);
  return reponse;
}

// Dans la fonction "boiteDialogue" vue plus haut,
// on modifie la boucle while ainsi :
{
  while ((reponse == GTK_RESPONSE_YES) || (reponse == GTK_RESPONSE_NO))
    {
      reponse = gtk_dialog_run(GTK_DIALOG(pDialogue));
      if (reponse == GTK_RESPONSE_NO)
        {
          boiteMessage(pDialogue);
        }
    }
}

Dans cet exemple, on ne traite pas la valeur retour de la boîte de message, puisque celle-ci n'a aucune incidence sur la suite des opérations. En effet, quelle que soit la façon dont la boîte de message s'arrête ici, cet arrêt a pour seule conséquence que de redonner la main à la fenêtre appelante, c'est-à-dire à la boîte de dialogue.

Date: 2015

Author: Antoine Rozenknop

Org version 7.8.03 with Emacs version 23

Validate XHTML 1.0