Les boîtes de dialogue
1. Présentation
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.1 Hiérarchie
GObject ->
GtkObject ->
GtkWidget ->
GtkContainer ->
GtkBin? ->
GtkWindow ->
GtkDialog
GObject ->
GtkObject ->
GtkWidget ->
GtkContainer ->
GtkBin? ->
GtkWindow ->
GtkDialog ->
GtkMessageDialog
1.2 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 :
2. La 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.
2.1 Création
La création est un peu plus complexe que d'habitude :
dialog = gtk.Dialog(title, parent, flags, 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 à None.
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êmes. Le plus simple étant bien sûr d'utiliser les valeurs classiques définies 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. FIXME
2.2 Ajout d'éléments dans la zone de travail
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 méthode
pack_start.
La question est maintenant de savoir comment accéder à la
GtkVBox pour utiliser la méthode
gtk_box_pack_start. Nous allons tout simplement utiliser l'attribut
vbox de
GtkDialog de cette manière :
nom_de_la_boite.vbox
La boîte de dialogue est maintenant complète.
2.3 Affichage de la boîte de dialogue
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 méthode
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 :
reponse = dialog.run()
Cette méthode 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 de retour. 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, run renvoie gtk.RESPONSE_NONE.
Une fois la valeur de retour connue, il ne reste plus qu'à agir en conséquence.
2.4 Programme 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.
# -*- Encoding: Latin-1 -*-
import gtk
class Demo:
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("GtkDialog")
self.window.set_default_size(320, 200)
self.window.connect("destroy", gtk.main_quit, None)
vbox = gtk.VBox(True, 0)
self.window.add(vbox)
button = gtk.Button("Cliquez ici pour saisir votre nom")
vbox.pack_start(button, False, True, 0)
self.label = gtk.Label()
vbox.pack_start(self.label, False, False, 0)
# Connexion du signal "clicked" pour ouvrir la boite de dialogue
button.connect("clicked", self.LancerBoite, self.window)
self.window.show_all()
gtk.main()
def LancerBoite(self, widget, window):
# Creation de la boite de dialogue
# 1 bouton Valider
# 1 bouton Annuler
boite = gtk.Dialog("Saisie du nom", window,
gtk.DIALOG_MODAL,
(gtk.STOCK_OK, gtk.RESPONSE_OK,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
# Creation de la zone de saisie
entry = gtk.Entry()
entry.set_text("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
boite.vbox.pack_start(entry, True, False, 0)
# Affichage des elements de la boite de dialogue
boite.vbox.show_all()
# On lance la boite de dialogue et on recupere la reponse
reponse = boite.run()
if reponse == gtk.RESPONSE_OK:
# L'utilisateur valide
nom = entry.get_text()
self.label.set_text(nom)
else:
# L'utilisateur annule (soit gtk.RESPONSE_CANCEL, soit gtk.RESPONSE_NONE)
self.label.set_text("Vous n'avez rien saisi !")
# Destruction de la boite de dialogue
boite.destroy()
if __name__ == '__main__':
Demo()
3. La boîte de message
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.
3.1 Création
L'unique fonction de ce widget est la fonction permettant de créer la boîte de dialogue :
dialog = gtk.MessageDialog?(parent, flags, type, buttons, 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 :
- gtk.MESSAGE_INFO : titre de la boîte "Information"
- gtk.MESSAGE_WARNING : titre de la boîte "Avertissement"
- gtk.MESSAGE_QUESTION : titre de la boîte "Question"
- gtk.MESSAGE_ERROR : titre de la boîte "Erreur".
Le deuxième nouveau paramètre
buttons, de type
GtkButtonsType, 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 :
- gtk.BUTTONS_NONE
- gtk.BUTTONS_OK
- gtk.BUTTONS_CLOSE
- gtk.BUTTONS_CANCEL
- gtk.BUTTONS_YES_NO
- gtk.BUTTONS_OK_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.
3.2 Programme 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.
# -*- Encoding: Latin-1 -*-
import gtk
def main():
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("GtkMessageDialog")
window.set_default_size(320, 200)
window.connect("destroy", gtk.main_quit, None)
vbox = gtk.VBox(True,0)
window.add(vbox)
about_btn = gtk.Button("A propos...")
vbox.pack_start(about_btn, True, False,0)
about_btn.connect("clicked", OnAboutBtn, window)
quitter_btn = gtk.Button(stock=gtk.STOCK_QUIT)
vbox.pack_start(quitter_btn, True, False, 0)
quitter_btn.connect("clicked", OnQuitBtn, window)
window.show_all()
gtk.main()
def OnAboutBtn(btn, data):
site = "http://www.gtk-fr.org"
# Creation de la boite de message
# Type : Information -> gtk.MESSAGE_INFO
# Bouton : 1 OK -> gtk.BUTTONS_OK
about = gtk.MessageDialog(data,
gtk.DIALOG_MODAL,
gtk.MESSAGE_INFO,
gtk.BUTTONS_OK,
"Cours GTK+ 2.0\n%s" % sSite)
# Affichage de la boite de message
about.run()
# Destruction de la boite de message
about.destroy()
def OnQuitBtn(widget, data):
# Creation de la boite de message
# Type : Question -> gtk.MESSAGE_QUESTION
# Boutons : 1 OUI, 1 NON -> gtk.BUTTONS_YES_NO
question = gtk.MessageDialog(data,
gtk.DIALOG_MODAL,
gtk.MESSAGE_QUESTION,
gtk.BUTTONS_YES_NO,
"Voulez vous vraiment\nquitter ce programme?")
# Affichage et attente d une reponse
reponse = question.run()
if reponse == gtk.RESPONSE_YES:
# OUI -> on quitte l application
gtk.main_quit()
elif reponse == gtk.RESPONSE_NO:
# NON -> on detruit la boite de message
question.destroy()
if __name__ == '__main__':
main()