Les boîtes de dialogue
Nous allons dans ce chapitre étudier un style de fenêtre particulier
: les boîtes de dialogue. Elles permettent de demander à l'utilisateur
des informations ou alors d'afficher des messages. Ces boîtes de dialogue
ressemblant fortement à des fenêtres classiques, il est normal
que le widget GtkDialog dérive directement de GtkWindow.

1. Utilisation d'une boîte de saisie
La saisie d'information via le widget GtkEntry ne s'effectue presque jamais
dans la fenêtre principale mais dans une boîte de dialogue. Nous
allons donc voir comment créer une telle boîte.
1.1 Constitution d'une boîte de dialogue

Comme nous pouvons le voir sur l'image ci-dessus, une boîte de dialogue
est constituée de trois éléments :
- une
GtkVBox globale (en rouge) qui contiendra tous les widgets
affichés ;
- une
GtkHSeparator (en vert) qui sert de séparation entre
la zone de saisie et la zone des boutons ;
- une
GtkHBox (en bleu) qui contiendra les boutons de réponse.
On peut donc ainsi distinguer deux zones différentes :
- la zone de travail au-dessus de la
GtkHSeparator ;
- la zone de réponse au-dessous de la
GtkHSeparator.
1.2 Création
La fonction de création est un peu plus complexe que d'habitude :
GtkWidget* gtk_dialog_new_with_buttons(const gchar *title,
GtkWindow *parent, GtkDialogFlags flags, const gchar *first_button_text, ...);
Le premier paramètre title n'est autre que le titre de
la boîte de dialogue.
Le deuxième paramètre parent sert à désigner
la fenêtre parente. Cette valeur peut être égale à
NULL.
Le troisième paramètre flags permet de définir certains
paramètres de la boîte de dialogue. Ce paramètre peut prendre
trois valeurs différentes :
GTK_DIALOG_MODAL : créer une boîte de dialogue
modale, c'est à dire que tant que l'utilisateur n'a pas cliqué
sur un des boutons de réponse, les autres fenêtres seront figées
;
GTK_DIALOG_DESTROY_WITH_PARENT : la boîte de dialogue
est détruite si la fenêtre parente est détruite ;
GTK_DIALOG_NO_SEPARATOR : la ligne de séparation entre
la zone de travail et la zone de réponse n'est pas affichée.
Enfin, le dernier paramètre est plutôt une liste de paramètres
permettant de définir les boutons de la boîte de dialogue ainsi
que les réponses qui leurs sont associées. Pour chaque bouton
que nous voulons ajouter, il faut définir le texte du bouton et le type
de réponse qui sera envoyé lorsque nous cliquerons sur le bouton.
Le texte du bouton peut, comme pour tous les boutons, être un texte normal,
un texte avec raccourci (Rappel : c'est de la forme "_Quitter") ou
même un GtkStockItem.
La valeur de la réponse, peut être un élément de
type GtkResponseType ou bien une valeur entière positive
que nous pouvons définir nous-même. Le plus simple étant
bien sûr d'utiliser les valeurs classiques définis par le type
GtkResponseType dont voici la liste :
GTK_RESPONSE_NONE ;
GTK_RESPONSE_REJECT ;
GTK_RESPONSE_ACCEPT ;
GTK_RESPONSE_DELETE_EVENT ;
GTK_RESPONSE_OK ;
GTK_RESPONSE_CANCEL ;
GTK_RESPONSE_CLOSE ;
GTK_RESPONSE_YES ;
GTK_RESPONSE_NO ;
GTK_RESPONSE_APPLY ;
GTK_RESPONSE_HELP.
Une fois que tous les boutons ont été définis, il faut
le dire à notre fonction de création. Pour cela, il suffit de
terminer la liste des paramètres par NULL.
La majeure partie des éléments de la boîte de dialogue
sont maintenant créés. Il reste cependant à ajouter les
éléments de la zone de travail pour que la boîte soit complète.
Une fois que tous les éléments à ajouter dans la zone de
travail sont créés, il suffit de les ajouter dans la boîte
de dialogue avec la fonction gtk_box_pack_start.
La question est maintenant de savoir comment passer la GtkVBox
en paramètre à la fonction gtk_box_pack_start. Nous
allons tout simplement utiliser l'opérateur -> pour l'élément
GtkDialog de cette manière :
GTK_DIALOG(nom_de_la_boite)->vbox;
La boîte de dialogue est maintenant complète.
1.3 Affichage
L'affichage de la boîte de dialogue comporte deux étapes. Tout
d'abord, il faut demander d'afficher tout le contenu de la GtkVBox qui est inclut
dans la boîte de dialogue avec la fonction gtk_widget_show_all.
Ensuite il faut afficher la boîte de dialogue en elle-même et attendre
la réponse de l'utilisateur avec cette fonction :
gint gtk_dialog_run(GtkDialog *dialog);
Le paramètre de cette fonction étant de type GtkDialog
il faut utiliser la macro de conversion GTK_DIALOG().
Cette fonction affiche l'intégralité de la boîte de dialogue,
mais rentre aussi dans une boucle récursive qui ne s'arrêtera que
lorsque l'utilisateur cliquera sur un des boutons. La valeur de retour correspond
à la valeur associée au bouton cliqué. Si, par hasard,
l'utilisateur quitte la boîte de dialogue en cliquant sur la croix de
celle-ci, gtk_dialog_run renvoie GTK_RESPONSE_NONE.
Une fois la valeur de retour connue, il ne reste plus qu'à agir en conséquence.
1.4 Exemple
L'exemple de ce chapitre est constitué d'une fenêtre principale
dans laquelle nous allons ajouter un GtkButton et un GtkLabel.
Lorsque l'utilisateur clique sur le GtkButton, une boîte de dialogue apparaîtra
et demandera à l'utilisateur de saisir son nom.
Cette boîte de dialogue sera constituée d'une GtkEntry,
d'un GtkButton "OK" et d'un GtkButton "Annuler".
Si l'utilisateur clique sur "OK" le contenu de la GtkEntry
sera copié dans le GtkLabel de la fenêtre principale
tandis que s'il clique sur "Annuler" on affichera "Vous
n'avez rien saisi." dans le GtkLabel.
1.5 Programme exemple
#include <stdlib.h>
#include <gtk/gtk.h> static
GtkWidget *pLabel;
static GtkWidget *pWindow;
void lancer_boite(void);
int main(int
argc, char **argv)
{
GtkWidget *pVBox;
GtkWidget *pButton;
gtk_init(&argc, &argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "GtkDialog");
gtk_window_set_default_size(GTK_WINDOW(pWindow),
320, 200);
g_signal_connect(G_OBJECT(pWindow), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
pVBox = gtk_vbox_new(TRUE, 0);
gtk_container_add(GTK_CONTAINER(pWindow), pVBox);
pButton = gtk_button_new_with_label("Cliquez
ici pour saisir votre nom");
gtk_box_pack_start(GTK_BOX(pVBox), pButton, FALSE,
TRUE, 0);
pLabel = gtk_label_new(NULL);
gtk_box_pack_start(GTK_BOX(pVBox), pLabel, FALSE,
FALSE, 0);
/* Connexion du signal
"clicked" pour ouvrir la boite de dialogue */
g_signal_connect(G_OBJECT(pButton), "clicked",
G_CALLBACK(lancer_boite), NULL);
gtk_widget_show_all(pWindow);
gtk_main();
return EXIT_SUCCESS;
}
void lancer_boite(void)
{
GtkWidget* pBoite;
GtkWidget* pEntry;
const gchar* sNom;
/* Creation de la boite
de dialogue */
/* 1 bouton Valider */
/* 1 bouton Annuler */
pBoite = gtk_dialog_new_with_buttons("Saisie
du nom",
GTK_WINDOW(pWindow),
GTK_DIALOG_MODAL,
GTK_STOCK_OK,GTK_RESPONSE_OK,
GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,
NULL);
/* Creation de la zone
de saisie */
pEntry = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(pEntry), "Saisissez
votre nom");
/* Insertion de la zone
de saisie dans la boite de dialogue */
/* Rappel : paramètre 1 de gtk_box_pack_start
de type GtkBox */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pBoite)->vbox),
pEntry, TRUE, FALSE, 0);
/* Affichage des elements
de la boite de dialogue */
gtk_widget_show_all(GTK_DIALOG(pBoite)->vbox);
/* On lance la boite de
dialogue et on recupere la reponse */
switch (gtk_dialog_run(GTK_DIALOG(pBoite)))
{
/*
L utilisateur valide */
case
GTK_RESPONSE_OK:
sNom
= gtk_entry_get_text(GTK_ENTRY(pEntry));
gtk_label_set_text(GTK_LABEL(pLabel),
sNom);
break;
/*
L utilisateur annule */
case
GTK_RESPONSE_CANCEL:
case
GTK_RESPONSE_NONE:
default:
gtk_label_set_text(GTK_LABEL(pLabel),
"Vous n'avez rien saisi !");
break;
}
/* Destruction de la boite
de dialogue */
gtk_widget_destroy(pBoite);
} |
| Résultat :



|
2. Les boîtes de messages.
Comme nous venons de le voir, le widget GtkDialog permet d'accélérer
la programmation de simple fenêtre de saisie. Pour ce qui est de l'affichage
de message, GTK+ offre un nouveau widget qui dérive directement de GtkDialog
: le widget GtkMessageDialog. Ce widget permet de créer une boîte
de dialogue complète avec une seule fonction.

2.1 Création.
L'unique fonction de ce widget est la fonction permettant de créer la
boîte de dialogue :
GtkWidget* gtk_message_dialog_new (GtkWindow *parent, GtkDialogFlags
flags, GtkMessageType type, GtkButtonsType buttons, const gchar *message_format,
...);
Les paramètres parent et flags sont identiques
à ceux du widget GtkDialog, nous ne reviendrons donc pas
dessus et allons nous concentrer sur les nouveaux paramètres.
Le tout premier type, permet de définir le texte qui sera
affiché dans la barre de titre de la boîte de dialogue ainsi que
l'icône correspondant. Ce paramètre est de type GtkMessageType
et peut prendre une des quatre valeurs suivantes :
| Valeur |
Titre de la boîte de dialogue |
Icône |
| GTK_MESSAGE_INFO |
Information |
 |
| GTK_MESSAGE_WARNING |
Avertissement |
 |
| GTK_MESSAGE_QUESTION |
Question |
 |
| GTK_MESSAGE_ERROR |
Erreur |
 |
Le deuxième nouveau paramètre buttons permet de définir
les boutons qui seront présents en bas de la boîte de dialogue.
Les valeurs autorisées sont les suivantes :
| Macro |
Les boutons |
Valeur de retour |
GTK_BUTTONS_NONE |
Aucun bouton |
Néant |
GTK_BUTTONS_OK |
Un bouton Ok |
GTK_RESPONSE_OK |
GTK_BUTTONS_CLOSE |
Un bouton Fermer |
GTK_RESPONSE_CLOSE |
GTK_BUTTONS_CANCEL |
Un bouton Annuler |
GTK_RESPONSE_CANCEL |
GTK_BUTTONS_YES_NO |
Un bouton Oui
Un bouton Non |
GTK_RESPONSE_YES
GTK_RESPONSE_NO |
GTK_BUTTONS_OK_CANCEL |
Un bouton Ok
Un bouton Annuler |
GTK_RESPONSE_OK
GTK_RESPONSE_CANCEL |
Et le dernier paramètre message_format est tout simplement
le texte qui sera affiché à l'intérieur de la boîte
de dialogue. Ce texte peut être formaté comme il est possible de
le faire avec la fonction printf.
2.2 Exemple.
Nous allons créer une fenêtre comportant deux boutons. Le premier
permettra d'afficher les informations habituelles d'une boîte de dialogue
"A propos...". Le deuxième offrira la possibilité de
quitter le programme, en passant par une demande de confirmation à l'utilisateur.
2.3 Programme exemple.
#include <stdlib.h>
#include <gtk/gtk.h> void
on_about_btn(GtkWidget *pBtn, gpointer data);
void on_quitter_btn(GtkWidget *pBtn, gpointer
data);
int main(int
argc, char **argv)
{
GtkWidget *pWindow;
GtkWidget *pVBox;
GtkWidget *pQuitterBtn;
GtkWidget *pAboutBtn;
gtk_init(&argc,&argv);
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "GtkMessageDialog");
gtk_window_set_default_size(GTK_WINDOW(pWindow),
320, 200);
g_signal_connect(G_OBJECT(pWindow), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
pVBox = gtk_vbox_new(TRUE,0);
gtk_container_add(GTK_CONTAINER(pWindow),pVBox);
pAboutBtn = gtk_button_new_with_label("A
propos...");
gtk_box_pack_start(GTK_BOX(pVBox), pAboutBtn,
TRUE, FALSE,0);
g_signal_connect(G_OBJECT(pAboutBtn), "clicked",
G_CALLBACK(on_about_btn), (GtkWidget*) pWindow);
pQuitterBtn = gtk_button_new_from_stock (GTK_STOCK_QUIT);
gtk_box_pack_start(GTK_BOX(pVBox), pQuitterBtn,
TRUE, FALSE, 0);
g_signal_connect(G_OBJECT(pQuitterBtn), "clicked",
G_CALLBACK(on_quitter_btn), (GtkWidget*) pWindow);
gtk_widget_show_all(pWindow);
gtk_main();
return EXIT_SUCCESS;
}
void on_about_btn(GtkWidget *pBtn, gpointer
data)
{
GtkWidget *pAbout;
gchar *sSite = "http://gtk.developpez.com";
/* Creation de la boite
de message */
/* Type : Information -> GTK_MESSAGE_INFO */
/* Bouton : 1 OK -> GTK_BUTTONS_OK */
pAbout = gtk_message_dialog_new (GTK_WINDOW(data),
GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
"Cours GTK+ 2.0\n%s",
sSite);
/* Affichage de la boite
de message */
gtk_dialog_run(GTK_DIALOG(pAbout));
/* Destruction de la boite
de message */
gtk_widget_destroy(pAbout);
}
void on_quitter_btn(GtkWidget* widget, gpointer
data)
{
GtkWidget *pQuestion;
/* Creation de la boite
de message */
/* Type : Question -> GTK_MESSAGE_QUESTION
*/
/* Boutons : 1 OUI, 1 NON -> GTK_BUTTONS_YES_NO
*/
pQuestion = gtk_message_dialog_new (GTK_WINDOW(data),
GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
"Voulez vous vraiment\nquitter
ce programme?");
/* Affichage et attente
d une reponse */
switch(gtk_dialog_run(GTK_DIALOG(pQuestion)))
{
case
GTK_RESPONSE_YES:
/*
OUI -> on quitte l application */
gtk_main_quit();
break;
case
GTK_RESPONSE_NO:
/*
NON -> on detruit la boite de message */
gtk_widget_destroy(pQuestion);
break;
}
} |
| Résultat :



|
3. En savoir plus :
3.1 Fonctions documentées
| GtkWidget* gtk_dialog_new(); |
Permet de créer un boîte de dialogue vierge.
Entrée(s) : rien. Sortie :
pointeur sur la boîte de dialogue. |
| void gtk_dialog_add_buttons(GtkDialog *dialog, const gchar
*first_button_text, ...); |
Ajoute des boutons à la boîte de dialogue.
Entrée(s) : dialog : la boîte de dialogue.
first_button_text, ... : texte et réponse des boutons.
Sortie : rien. |
| GtkWidget* gtk_dialog_add_button(GtkDialog *dialog, const
gchar *button_text, gint response_id); |
Ajoute un bouton à la boîte de dialogue.
Entrée(s) : dialog : la boîte de dialogue.
button_text : texte du bouton. response_id : valeur
de retour du bouton . Sortie : pointeur sur le nouveau
bouton. |
| gboolean gtk_dialog_get_has_separator(GtkDialog *dialog); |
Pour savoir si la boîte de dialogue possède
une barre de séparation. Entrée(s) :
dialog : la boîte de dialogue. Sortie : TRUE
si la barre de séparation est présente, FALSE sinon. |
| void gtk_dialog_set_has_separator(GtkDialog *dialog, gboolean
setting); |
Définit si la boîte de dialogue possède
une barre de séparation Entrée(s) :
dialog : la boîte de dialogue en question setting
: TRUE pour l'ajouter, FALSE sinon. Sortie : rien. |
3.2 Fonctions non documentées
void gtk_dialog_response (GtkDialog *dialog, gint response_id);
void gtk_dialog_set_default_response (GtkDialog *dialog, gint response_id);
void gtk_dialog_set_response_sensitive(GtkDialog *dialog, gint response_id, gboolean
setting);
void gtk_dialog_add_action_widget (GtkDialog *dialog, GtkWidget *child, gint response_id);
Date de mise à jour : 17 mai 2003