Après un chapitre sur les signaux et les slots riche en nouveaux concepts, on relâche ici un peu la pression.
Nous allons découvrir les boîtes de dialogue usuelles, aussi appelées "common dialogs" par nos amis anglophones.

Qu'est-ce qu'une boîte de dialogue usuelle ? C'est une fenêtre qui sert à remplir une fonction bien précise. Par exemple, on connaît la boîte de dialogue "message" qui affiche un message et ne vous laisse d'autre choix que de cliquer sur le bouton OK. Ou encore la boîte de dialogue "ouvrir un fichier", "enregistrer un fichier", "sélectionner une couleur", etc.
On ne s'amuse pas à recréer "à la main" ces fenêtres à chaque fois. On profite de fonctions système pour ouvrir des boîtes de dialogue pré-construites.
PyQt s'adapte à l'OS pour afficher une boîte de dialogue qui corresponde aux formes habituelles de votre OS.
En clair : attendez-vous à un chapitre simple qui vous donnera de nombreux outils pour pouvoir interagir avec l'utilisateur de votre programme !



Sommaire du chapitre :

Icône du chapitre



1 -Afficher un message

Le premier type de boîte de dialogue que nous allons voir est le plus courant : la boîte de dialogue "afficher un message".

Nous allons créer un bouton sur notre fenêtre de type MaFenetre qui appellera un slot personnalisé. Ce slot ouvrira la boîte de dialogue. En clair, un clic sur le bouton doit pouvoir ouvrir la boîte de dialogue.

Les boîtes de dialogue "afficher un message" sont contrôlées par la classe QMessageBox. Vous pouvez commencer par faire l'import correspondant dans "MaFenetre.py" pour ne pas l'oublier :

Cadre1

(l'instruction from PyQt4.QtGui import * fera très bien l'affaire)

1.1 -Quelques rappels et préparatifs

Pour que l'on soit sûr de travailler ensemble sur le même code, je vous donne le code source des fichiers MaFenetre.py et main.py sur lesquels je vais travailler. Ils ont été simplifiés au maximum histoire d'éviter le superflu.

#! /usr/bin/python
#-*-coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import os,sys
class MaFenetre(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setFixedSize(230,120)
        self.boutonDialogue = QpushButton(self.trUtf8(
                   "Ouvrir la boîte de dialogue"), 
                    self)
        self.boutonDialogue.move(40, 50)
        self.connect(self.boutonDialogue, 
                     SIGNAL("clicked()"),  
                     self.ouvrirDialogue)
    def ouvrirDialogue(self):
        # Vous insérerez le code d'ouverture 
        # des boîtes de dialogue ici
        pass


C'est très simple. Nous avons créé un bouton dans la boîte de dialogue qui appelle le slot personnalisé ouvrirDialogue(). C'est dans ce slot que nous nous chargerons d'ouvrir une boîte de dialogue.

Au cas où certains se poseraient la question, notre main.py n'a pas changé. Allez, je vous le redonne. Je suis trop sympa je sais, ne me remerciez pas :-°

#! /usr/bin/python
#-*-coding: utf-8 -*-
from PyQt4.QtGui import *
from maFenetre_5_0 import *
import sys

def main(args):
    a=QApplication(args)
    # Création d'un widget qui servira de fenêtre
    fenetre=MaFenetre()
    fenetre.show()
    r=a.exec_()
    return r

if __name__=="__main__":
    main(sys.argv)

1.2 -Ouvrir une boîte de dialogue avec une méthode statique

Bien, place à l'action maintenant !
La classe QMessageBox permet de créer des objets de type QMessageBox (comme toute classe qui se respecte :-° ). En voici quelques méthodes :

Je vous rappelle qu'une méthode statique dans une classe est une méthode qui n'a pas besoin d'une instance de cette classe pour être appelée. Par exemple la méthode information de la classe QmessageBox ci-dessous est invoquée par l'instruction QmessageBox.information(...).
Une méthode qui n'est pas statique doit être invoquée par une instance de la classe. Par exemple :
l=['a','b','c']
l.append('d')                #OK, l est une instance de list
list.append('w')             #interdit, list n'est pas une instance de list
QmessageBox.information(...) #OK, information et une methode statique de                    
                             #QmessageBox

i ) QMessageBox::information

La méthode statique information() permet d'ouvrir une boîte de dialogue constituée d'une icône "information".
Son prototype C++ est le suivant :

StandardButton information ( QWidget * parent, 
                             const QString & title, 
                             const QString & text, 
                             StandardButtons buttons = Ok, 
                             StandardButton defaultButton = NoButton );


Seuls les 3 premiers paramètres sont obligatoires, les autres ayant comme vous le voyez une valeur par défaut.
Ces 3 premiers paramètres sont :



Testons donc un code très simple. Voici le code du slot ouvrirDialogue() :

    def ouvrirDialogue(self):
        QMessageBox.information(self, 
                self.trUtf8("Titre de la fenêtre"), 
                self.trUtf8("Bonjour et bienvenue à tous les Zéros !"))


Le résultat est une boîte de dialogue comme vous avez l'habitude d'en voir, constituée d'un bouton OK :

Boîte de dialogue information



Vous noterez que lorsque la boîte de dialogue est ouverte, on ne peut plus accéder à sa fenêtre parente qui est derrière. On dit que la boîte de dialogue est une fenêtre modale : c'est une fenêtre qui "bloque" temporairement son parent en attente d'une réponse de l'utilisateur.

A l'inverse, on dit qu'une fenêtre est non modale quand on peut toujours accéder à la fenêtre derrière. C'est le cas en général des boîtes de dialogue "Rechercher un texte" dans les éditeurs de texte.

Comble du raffinement (j'aime bien cette expression :D ), il est même possible de mettre en forme son message à l'aide de balises (X)HTML pour ceux qui connaissent. Si vous ne connaissez pas, il est toujours temps d'apprendre le HTML, j'ai fait un tuto il faut en profiter ;)

Exemple de boîte de dialogue "enrichie" avec du code HTML :

QMessageBox.information(self, 
                        self.trUtf8("Titre de la fenêtre"), 
                        self.trUtf8("Bonjour et bienvenue 
                           <br> à tous les <strong>Zéros</strong> !"))



Boîte de dialogue information avec HTML

ii ) QMessageBox::warning

Si la boîte de dialogue "information" sert à informer l'utilisateur par un message, la boîte de dialogue warning le met en garde contre quelque chose. Elle est généralement accompagné d'un "ding" caractéristique.
Elle s'utilise de la même manière que QMessageBox::information, mais cette fois l'icône change :

QMessageBox.warning(self, 
             self.trUtf8("Titre de la fenêtre"), 
             self.trUtf8("Attention, vous êtes peut-être un Zéro !"));



Boîte de dialogue attention

iii ) QMessageBox::critical

Quand c'est trop tard et qu'une erreur s'est produite, il ne vous reste plus qu'à utiliser la méthode critical() : ici, je teste deux versions, l'une avec gestion du codage Utf8, l'autre sans.

QMessageBox.critical(self, 
   self.trUtf8("Titre de la fenêtre"),
   self.trUtf8("Vous n'êtes pas un Zéro, sortez ou j'appelle la police !"))
QMessageBox.critical(self, 
        "Titre de la fenêtre",
        "Vous n'êtes pas un Zéro, sortez ou j'appelle la police !")



Boîte de dialogue erreur critique

Boîte de dialogue erreur critique

iv ) QMessageBox::question

Si vous avez une question à poser à l'utilisateur, c'est la boîte de dialogue qu'il vous faut !

QmessageBox.question(self, 
         self.trUtf8("Titre de la fenêtre"), 
         self.trUtf8("Dites voir, je me posais la question comme ça, 
                      êtes-vous vraiment un Zéro ?"))



Boîte de dialogue question



C'est bien joli mais... comment peut-on répondre à la question avec un simple bouton OK ?

Par défaut, c'est toujours un bouton OK qui s'affiche. Mais dans certains cas, comme lorsqu'on pose une question, il faudra afficher d'autres boutons pour que la boîte de dialogue ait du sens.

v ) Personnaliser les boutons de la boîte de dialogue

Pour personnaliser les boutons de la boîte de dialogue, il faut utiliser le 4ème paramètre de la méthode. Ce paramètre accepte une combinaison de valeurs prédéfinies, séparées par un OR (la barre verticale |). On appelle cela des flags.
Vous vous y habituerez vite vous verrez, c'est juste une façon pratique d'envoyer des options à une fonction.

Pour ceux qui se poseraient la question, le 5ème et dernier paramètre de la fonction permet d'indiquer quel est le bouton par défaut. On change rarement cette valeur car Qt choisit généralement le bouton qui convient le mieux par défaut.

La liste des flags disponibles est donnée par la documentation. Vous avez du choix comme vous pouvez le voir.
Si on veut placer les boutons "Oui" et "Non", il nous suffit de combiner les valeurs "QMessageBox::Yes" et "QMessageBox::No"

QmessageBox.question(this, 
     self.trUtf8("Titre de la fenêtre"), 
     self.trUtf8(trUtf8("Dites voir, je me posais la question comme ça, 
                                      êtes-vous vraiment un Zéro ?"), 
     QmessageBox.Yes | QmessageBox.No)



Les boutons apparaissent alors :

Boîte de dialogue question en anglais


Horreur ! Malédiction ! Enfer et damnation !
L'anglais me poursuit, les boutons sont écrits en anglais. Catastrophe qu'est-ce que je vais faire au secouuuuuurs !!!

En effet, les boutons sont écrits en anglais. Mais ce n'est pas grave du tout, les applications PyQt peuvent être facilement traduites, je vous en avais parlé en introduction de cette partie.

On ne va pas rentrer dans les détails du fonctionnement de la traduction, on aura l'occasion d'en reparler plus longuement plus tard. Je vais vous donner un code à placer dans le main, et vous allez l'utiliser gentiment sans poser de questions.
Attention, j'ai dit : sans poser de question. On n'aime pas trop les gens qui posent des questions ici. Un accident est si vite arrivé... :diable:

#! /usr/bin/python
#-*-coding: utf-8 -*-
from PyQt4.QtGui import *
from maFenetre_5_0 import *
import sys

def main(args):
    a=QApplication(args)
    locale = QLocale.system().name()
    translator=QTranslator ()
    translator.load(QString("qt_") + locale,   
                  LibraryInfo.location(QLibraryInfo.TranslationsPath))
    a.installTranslator(translator)

    # Création d'un widget qui servira de fenêtre
    fenetre=MaFenetre()
    fenetre.show()
    r=a.exec_()
    return r

if __name__=="__main__":
    main(sys.argv)// main.cpp



Les lignes ajoutées ont été surlignées.
Normalement, votre application devrait maintenant afficher des boutons en français :

Boîte de dialogue question en français

Et voilà le travail ! :D



C'est cool, mais comment je fais pour savoir sur quel bouton l'utilisateur a cliqué ? Hein, hein ?


Quoi ? Encore une question ?
Vous savez, vous réduisez votre espérance de vie avec toutes les questions que vous posez aujourd'hui. Enfin moi j'dis ça comme ça :-°

Bon ok, cette question est pertinente, je peux y répondre. Je dois y répondre même. Alors allons-y !

vi ) Récupérer la valeur de retour de la boîte de dialogue

Les méthodes que nous venons de voir retournent un entier (int). On peut tester facilement la signification de ce nombre à l'aide des valeurs prédéfinies par Qt (comme quoi les énumérations c'est pratique !).

def ouvrirDialogue(self):
   reponse =QmessageBox.question(self, 
                self.trUtf8("Interrogatoire"),
                self.trUtf8("Dites voir,je me posais la question comme ça, 
                            <br>êtes-vous vraiment un Zéro ?"),
                QMessageBox.Yes | QMessageBox.No)
   if (reponse == QMessageBox.Yes):
      QMessageBox.information(self,"Interrogatoire", 
                 self.trUtf8("Alors bienvenue chez les Zéros !"))
   elif (reponse == QMessageBox.No):
      QMessageBox.critical(self, 
          "Interrogatoire", 
          self.trUtf8("Sapajou ! Coloquinte ! Tchouk-tchouk-Nougat ! 
            <br>Ingrat ! Lâche ! Traître !
            <br>Sors d'ici ou j'appelle les keufs !"))



Voici un schéma de ce qui peut se passer :

Traitement du retour de la boîte de dialogue



C'est ma foi clair, non ? :D

Petite précision quand même : le type de retour exact de la méthode n'est pas int mais QMessageBox::StandardButton. Or, il s'agit là d'une énumération, et comme vous le savez probablement, une énumération n'est rien d'autre que le remplacement de nombres par des mots plus lisibles. Utiliser un int revient donc strictement au même.
Si un rappel sur les énumérations s'impose parce que je viens de vous parler en chinois, relisez donc le cours sur les énumérations issu du tutoriel du langage C.



2 -Saisir une information

Les boîtes de dialogues précédentes étaient un peu limitées car, à part présenter différents boutons, on ne pouvait pas trop interagir avec l'utilisateur.

Si vous souhaitez que votre utilisateur saisisse une information, ou encore fasse un choix parmi une liste, les boîtes de dialogue de saisie sont idéales. Elles sont gérées par la classe QInputDialog, que je vous conseille d'inclure dès maintenant dans MaFenetre.py.

Les boîtes de dialogue "saisir une information" peuvent être de 4 types. Nous allons les voir dans l'ordre :
Chacune de ces fonctionnalités est assurée par une méthode statique différente.

2.1 -Saisir un texte (QInputDialog.getText)

La méthode getText() ouvre une boîte de dialogue qui permet à l'utilisateur de saisir un texte.
Son prototype C++ est :

QString QInputDialog::getText ( QWidget * parent, 
                         const QString & title, 
                         const QString & label, 
                         QlineEdit::EchoMode mode = QLineEdit::Normal, 
                         const QString & text = QString(), 
                         bool * ok = 0, 
                         Qt::WindowFlags f = 0 );



L'équivalent Python, extrait de la doc PyQt : /usr/share/doc/pyqt4/qinputdialog.html#getText

(QString, bool ok) QInputDialog.getText (QWidget parent, 
                        QString title, 
                        QString label, 
                        QLineEdit.EchoMode echo = QLineEdit.Normal, 
                        QString text = QString(), 
                        Qt.WindowFlags f = 0)


Vous pouvez tout d'abord constater que la méthode retourne un tuple (QString, bool ok) constitué d'un QString, et d'un booléen. Un Qstring est une chaîne de caractères de Qt.
Les paramètres signifient, dans l'ordre :


Heureusement, comme vous pouvez le constater en lisant le prototype, certains paramètres possèdent des valeurs par défaut ce qui fait qu'ils ne sont pas obligatoires.

Reprenons notre code de tout à l'heure et cette fois, au lieu d'afficher une QMessageBox, nous allons afficher une QInputDialog lorsqu'on clique sur le bouton de la fenêtre.

pseudo, ok =QInputDialog.getText(self, 
                                 self.trUtf8("Pseudo"),
                                 self.trUtf8("Quel est votre pseudo ?"),
                                 QLineEdit.Normal, Qstring())



En une ligne, je crée un QString et je lui affecte directement la valeur retournée par la méthode getText(). J'aurais aussi bien pu faire la même chose en deux lignes, mais ç'aurait été plus long et je suis une feignasse ^^
Ici, la méthode QinputDialog.getText modifie et renvoit deux valeurs : le texte entré (pseudo) et un booléen (ok) qui indique quel bouton (Ok ou annuler) a été cliqué par l'utilisateur.


En C++, une méthode ne peut renvoyer qu'une seule valeur. Les programmeurs de Qt ont choisi de renvoyer le texte entré par l'utilisateur, tandis que la valeur ok du bouton cliqué est passée en paramètre par adresse (bool * ok = 0).
En python, les deux valeurs sont créées et modifiées par la méthode, puis renvoyées dans le tuple (pseudo,ok)


La boîte de dialogue devrait ressembler à cela :

Saisie de texte



On peut aller plus loin et vérifier si le bouton OK a été actionné, et si c'est le cas on peut alors afficher le pseudo de l'utilisateur dans une QMessageBox.

def ouvrirDialogue(self):
    pseudo,ok=QInputDialog.getText(self, 
                   self.trUtf8("Pseudo"),
                   self.trUtf8("Quel est votre pseudo ?"),
                   QlineEdit.Normal,
                   QString())
    if (ok and not pseudo.isEmpty()):
        msg=self.trUtf8("Bonjour " + str(pseudo) + ", ça va ?")
        QMessageBox.information(self, 
                    self.trUtf8("Pseudo"), msg)
    else :
        msg=self.trUtf8 ("Mon p'tit gars,\ 
            va falloir me donner ton pseudo, et vite!")
        QmessageBox.critical(self,"Pseudo",msg))



Ici, on récupère dans ok la valeur du booléen qui reçoit l'information "Le bouton OK a-t-il été cliqué ?".

Je peux ensuite faire un test, d'où la présence de mon if. Je vérifie 2 choses :


Si un pseudo a été entré et que l'utilisateur a cliqué sur OK, alors une boîte de dialogue lui souhaite la bienvenue. Sinon, une erreur est affichée.

Ce schéma présente ce qui peut se produire :

Schéma des possibilités de réaction du programme getText



Exercice : essayez d'afficher le pseudo de l'utilisateur quelque part sur la fenêtre mère, par exemple sur le bouton.

2.2 -Saisir un nombre entier, un nombre décimal, un élément de liste

Toutes ces saisies sont de nature analogue à la saisie de texte. Les prototypes sont décrits ci-dessous.

Pour les paramètres, voir la documentation.

Si vous avez installé la doc python-qt4, elle est probablement dans : /usr/share/doc/python-qt4-doc/html/qinputdialog.html

La classe MaFenetre ouvre ces quatre dialogues de saisie.

La saisie d'un double (getDouble) est pratiquement identique à celle d'un entier (getInteger), à la différence près qu'il y a un paramètre qui permet d'indiquer le nombre maximal de chiffres après la virgule autorisés (paramètre decimals).

La saisie de texte (getText) a été vue ci-dessus

La saisie d'un élément de liste avec un menu déroulant (getItem), est légèrement plus délicat puisqu'il faut construire une QstringList (la liste des valeurs possibles). C'est ce que réalise l'instruction QstringList(['a','b','c','d']). On peut aussi citer append() qui permet d'ajouter un élément à la fin de la liste.

(int, bool ok) QInputDialog.getInteger (QWidget parent, 
                         QString title, 
                         QString label, 
                         int value = 0, 
                         int minValue = -2147483647, 
                         int maxValue = 2147483647, 
                         int step = 1, 
                         Qt.WindowFlags f = 0)
(QString, bool ok) QInputDialog.getItem (QWidget parent, 
                         QString title, 
                         QString label, 
                         QStringList list, 
                         int current = 0, 
                         bool editable = True, 
                         Qt.WindowFlags f = 0)
(QString, bool ok) QInputDialog.getText (QWidget parent, 
                         QString title, 
                         QString label, 
                         QLineEdit.EchoMode echo = QlineEdit.Normal,
                         QString text = QString(), 
                         Qt.WindowFlags f = 0)
(float, bool ok) QInputDialog.getDouble (QWidget parent, 
                         QString title, 
                         QString label, 
                         float value = 0, 
                         float minValue = -2147483647, 
                         float maxValue = 2147483647, 
                         int decimals = 1, 
                         Qt.WindowFlags f = 0)



Voici un exemple d'utilisation :

#! /usr/bin/python
#-*-coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import os,sys
class MaFenetre(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.setFixedSize(230,120)
        texte,ok = QInputDialog.getText(self, 
                       self.trUtf8("Texte"), 
                       self.trUtf8("Entrez un texte"));
        entier,ok = QinputDialog.getInteger(self,
                       self.trUtf8("Entier"), 
                       self.trUtf8("Entrez un nombre entier"), 
                       3,0,1000,2);
        decimal,ok = QInputDialog.getDouble(self, 
                       self.trUtf8("Décimal"), 
                       self.trUtf8("Entrez un nombre décimal"));
        item,ok = QInputDialog.getItem(self, 
                       self.trUtf8("Liste"), 
                       self.trUtf8("Choisissez dans la liste"),
                       map(self.trUtf8,
                       [Aneto","Palas","Valluna","Faïal"]));
        msg="- "+texte+
            "<br>- "+str(entier)+
            "<br>- "+str(decimal)+
            "<br>- "+ item
        ok=QMessageBox.information(self,
                      self.trUtf8("Vos données : "), 
                      msg)

Et les boites de dialogue correspondantes

Et la boite d'information fournie à la fin du programme

3 -Sélectionner une police

La boîte de dialogue "Sélectionner une police" est une des boîtes de dialogue standard les plus connues. Nul doute que vous l'avez déjà rencontrée dans l'un de vos programmes favoris.

La boîte de dialogue de sélection de police est gérée par la classe QFontDialog. Celle-ci propose en gros une seule méthode statique surchargée (il y a plusieurs façons de l'utiliser), comme vous pouvez le constater sur la doc de QFontDialog.
Prenons le prototype le plus compliqué, juste pour la forme :D

(QFont, bool ok) getFont (QFont def, QWidget parent, QString caption)

Les paramètres se comprennent normalement assez facilement.

La méthode renvoit la police sélectionnée et notre booléen "ok" qui permet de savoir si l'utilisateur a cliqué sur OK ou a annulé.
On peut spécifier une police par défaut (def), il faudra envoyer un objet de type QFont. Voilà justement que la classe QFont réapparaît :)

Le widget parent de la boite de dialogue
Enfin, la chaîne caption correspond au message qui sera affiché en haut de la fenêtre.

Enfin, et surtout, la méthode retourne un objet de type QFont correspondant à la police qui a été choisie.

Testons ! Histoire d'aller un peu plus loin, je propose que la police que nous aurons sélectionnée soit immédiatement appliquée au texte de notre bouton, par l'intermédiaire de la méthode setFont() que nous avons appris à utiliser il y a quelques chapitres.

def ouvrirDialogue(self):
    police,ok=QFontDialog.getFont(
                 self.boutonDialogue.font(), 
                 self, 
                 "Choisissez une police")
    if ok : self.boutonQuit.setFont(police)



Comme vous l'avez remarqué que j'ai rajouté un bouton quit() à ma fenètre principale.


La méthode getFont prend comme police par défaut celle qui est utilisée par notre bouton boutonDialogue (rappelez-vous, font() est une méthode accesseur qui renvoie un QFont).
On teste si l'utilisateur a bien validé la fenêtre, et si c'est le cas on applique la police qui vient d'être choisie à notre bouton.

C'est l'avantage de travailler avec les classes de PyQt : elles sont cohérentes. La méthode getFont renvoie un QFont, et ce QFont nous pouvons l'envoyer à notre tour à notre bouton pour qu'il change d'apparence.

Le résultat ? Le voici :



Attention le bouton ne se redimensionne pas tout seul. Vous pouvez le rendre plus large de base si vous voulez, ou bien le redimensionner après le choix de la police.



4 -Sélectionner une couleur

Dans la même veine que la sélection de police, on connaît probablement tous la boîte de dialogue "Sélection de couleur".
Utilisez la classe QColorDialog et sa méthode statique getColor().

QColor getColor (QColor init = Qt.white, QWidget parent = None)



Elle retourne un objet de type QColor. Vous pouvez préciser une couleur par défaut, en envoyant un objet de type QColor ou en utilisant une des constantes prédéfinies de couleur. En l'absence de paramètre, c'est la couleur blanche qui sera sélectionnée comme nous l'indique le prototype.

Si on veut tester le résultat en appliquant la nouvelle couleur au bouton, c'est un petit peu compliqué. En effet, il n'existe pas de méthode setColor pour les widgets, mais une méthode setPalette qui sert à indiquer une palette de couleurs. Je vous laisse vous renseigner plus amplement si vous le désirez sur la classe QPalette qui est intéressante.

Le code que je vous propose ci-dessous ouvre une boîte de dialogue de sélection de couleur, puis crée une palette dont la couleur du texte correspond à la couleur qu'on vient de sélectionner, et applique enfin cette palette au bouton :

def ouvrirDialogue(self):
    couleur=QColorDialog.getColor(Qt.white,self)
    palette=QPalette() 
    palette.setColor(QPalette.Button, couleur)
    self.boutonQuit.setPalette(palette)


Une palette contient les règles pour colorer les différents éléments d'un widget. Plus précisément : une palette contient un groupe de couleur pour chaque état (Active, Disabled, et Inactive) du widget. Chacun de ces trois groupes de couleurs possède une description des couleurs attribuées aux différents éléments du widget. Les couleurs contenues dans un groupe sont : la couleur des boutons, du texte des boutons, du fond de la fenêtre, du texte de la fenêtre, du texte en surbrillance, etc... Ainsi par exemple, l'instruction palette.setColor(QPalette.Button, couleur) demande de mettre la couleur des boutons de ''palette'' à la valeur ''couleur''. A chaque widget est ensuite associée une palette.


Le résultat de l'application est le suivant :



5 -Sélection d'un fichier ou d'un dossier

Allez, plus que la sélection de fichiers et de dossiers et on aura fait le tour d'à peu près toutes les boîtes de dialogue usuelles qui existent ! :D

La sélection de fichiers et de dossiers est gérée par la classe QFileDialog qui propose elle aussi des méthodes statiques faciles à utiliser.

Cette section sera divisée en 3 parties :

5.1 -Sélection d'un dossier existant (QFileDialog::getExistingDirectory)

Bon je ne vous donne plus le prototype, vous devriez être assez grands pour le retrouver dans la doc ;)
On peut utiliser la méthode statique aussi simplement que comme ceci :

def ouvrirDialogue(self):
    dossier = QFileDialog.getExistingDirectory(self)
    QMessageBox.information(self, 
             self.trUtf8("Répertoire"), 
             self.trUtf8("Vous avez sélectionné :\n")+dossier)



Elle retourne un QString contenant le chemin complet vers le dossier demandé.
La fenêtre qui s'ouvre devrait ressembler à cela :

Sélectionner un dossier

5.2 -Ouverture d'un fichier (QFileDialog::getOpenFileName)

La célèbre boîte de dialogue "Ouverture d'un fichier" est gérée par getOpenFileName().
Sans paramètres particuliers, la boîte de dialogue permet d'ouvrir n'importe quel fichier.

Vous pouvez néanmoins créer un filtre (4ème paramètre) pour afficher par exemple uniquement les images.

Ce code demande d'ouvrir un fichier image. Le chemin vers le fichier est stocké dans un QString, que l'on affiche ensuite via une QMessageBox :

def ouvrirDialogue(self):
  fichier = QfileDialog.getOpenFileName(
                       self, 
                       "Ouvrir un fichier", 
                       "/home/puiseux/images", 
                       "Images (*.png *.gif *.jpg *.jpeg)")
  if fichier:
     QmessageBox.information(
                  self, 
                  "Fichier", 
                  self.trUtf8("Vous avez sélectionné :\n") + fichier)



Le troisième paramètre de getOpenFileName est le nom du répertoire par défaut dans lequel l'utilisateur est placé.
Grâce au 4ème paramètre j'ai choisi de filtrer les fichiers. Seules les images de type PNG, GIF, JPG et JPEG s'afficheront.

Résultat :

Ouvrir un fichier

Le principe de cette boîte de dialogue est de vous donner le chemin complet vers le fichier, mais pas de vous ouvrir ce fichier. C'est à vous ensuite de faire les opérations nécessaires pour ouvrir le fichier et l'afficher dans votre programme.

A noter aussi la fonction getOpenFileNames (notez le "s" à la fin) qui autorise la sélection de plusieurs fichiers. La principale différence est qu'au lieu de retourner un QString, elle retourne un QStringList (liste de chaînes). Tiens, comme on se retrouve !

5.3 -Enregistrement d'un fichier (QFileDialog::getSaveFileName)

C'est le même principe que la méthode précédente, à la différence près que la personne peut cette fois spécifier un nom de fichier qui n'existe pas pour l'enregistrement. Le bouton "Ouvrir" est remplacé par "Enregistrer".


fichier = QfileDialog.getSaveFileName(
            this, 
           "Enregistrer un fichier", 
            QString(), 
           "Images (*.png *.gif *.jpg *.jpeg)")



Enregistrer un fichier

Je vous avais promis un chapitre simple, vous avez eu un chapitre simple !

En effet, les méthodes statiques ne sont rien d'autre que des "fonctions" comme en langage C, elles ne nécessitent donc pas de créer d'objets. Comme quoi, parfois le modèle objet est inadapté et ici c'était clairement le cas. Pour la plupart des classes que nous avons vues, on peut s'en sortir sans créer le moindre objet.

Ces considérations mises à part, le modèle objet reste quoiqu'il en soit très pratique lorsqu'on crée des GUI comme on le fait là. Et je peux vous dire qu'on n'a pas fini de tout découvrir ^^

A titre informatif, il existe quelques autres boîtes de dialogue usuelles un peu plus rares et surtout un peu plus complexes à utiliser. Je pense notamment à :


Ceci étant, vous pouvez aussi lire la documentation si vous en avez besoin maintenant, il y a tout ce qu'il faut dessus.

Mais... mais... je sais pas lire une doc moi, je sais pas où chercher l'information dont j'ai besoin, je suis perdu j'y comprends rien :(


Ah ouais ? C'est ce qu'on va voir !
On vous a pas encore fait de tuto pour vous apprendre à lire une doc à ce que je sache ? Alors c'est le moment d'apprendre !