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 :
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 :
(l'instruction from
PyQt4.QtGui import * fera très bien l'affaire)
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)
|
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 classeQmessageBoxci-dessous est invoquée par l'instructionQmessageBox.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
|
QMessageBox::informationLa 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 :
parent
: (un pointeur vers) la fenêtre parente (qui doit être de
type QWidget ou hériter de QWidget).
Vous pouvez envoyer NULL en paramètre
si vous ne voulez pas que votre boîte de dialogue ait une fenêtre
parente, mais ce sera plutôt rare.
title
: le titre de la boîte de dialogue (affiché en haut de la
fenêtre).
text
: le texte affiché au sein de la boîte de dialogue.
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 :

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
), 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> !"))
|

QMessageBox::warningSi 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 !"));
|

QMessageBox::criticalQuand 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 !")
|


QMessageBox::questionSi 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 ?"))
|

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.
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 :

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é...
#! /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 :

Et voilà le travail
!
![]()
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 !
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 :

C'est ma foi
clair, non ?
![]()
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.
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.
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 :
parent : la fenêtre parente. Peut être mis à None pour ne pas indiquer de fenêtre parente.
title : titre de la fenêtre affiché en haut.
label : texte affiché dans la fenêtre.
mode :
mode d'édition du texte. Permet de dire si on veut que les lettres
s'affichent quand on tape, ou si elles doivent être remplacées par
des astérisques (pour les mots de passe) ou si aucune lettre ne
doit s'afficher. Toutes les options sont dans la
doc. Par défaut, les lettres s'affichent normalement
(QLineEdit::Normal).
text : le texte par défaut dans la zone de saisie.
ok : un pointeur vers un booléen pour que Qt puisse vous dire si l'utilisateur a cliqué sur OK ou sur Annuler.
f = quelques flags (options) permettant d'indiquer si la fenêtre est modale (bloquante) ou pas. Les valeurs possibles sont détaillées par la doc.
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 :

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 le bouton OK a été cliqué
Et si le texte
n'est pas vide (la méthode isEmpty de
QString sert à faire ça, vous ne
pouviez pas la connaître, sauf en lisant la doc
de QString bien sûr
).
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 :

Exercice
: essayez d'afficher le pseudo de l'utilisateur quelque part sur la
fenêtre mère, par exemple sur le bouton.
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

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
![]()
(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.
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, etInactive) 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'instructionpalette.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 :



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 !
![]()
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
:
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 :


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 :


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 !
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)")
|


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 à :
QProgressDialog
: affiche une boîte de dialogue avec une barre de progression et un
bouton "Annuler". Cela permet de faire patienter
l'utilisateur le temps qu'une longue opération s'exécute. Cette
classe est très intéressante mais il vaut mieux qu'on la voie en
pratique si on a l'occasion, car Qt cherche à estimer le temps
restant pour savoir s'il doit afficher ou non la fenêtre. C'est
plus intéressant de le voir dans un cas très concret donc.
QWizard
: affiche un assistant, avec les boutons "Suivant",
"Précédent", "Terminer"... Là encore il vaut
mieux avoir un projet concret pour apprendre à utiliser cette
classe car elle est assez complexe.
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 !