I. L'article original▲
Qt Quarterly est une revue trimestrielle électronique proposée par Nokia à destination des développeurs et utilisateurs de Qt. Vous pouvez trouver les versions originales.
Nokia, Qt, Qt Quarterly et leurs logos sont des marques déposées de Nokia Corporation en Finlande et/ou dans les autres pays. Les autres marques déposées sont détenues par leurs propriétaires respectifs.
Cet article est la traduction de l'article Reordering OK and Cancel paru dans la Qt Quarterly Issue 19.
Cet article est une traduction d'un des tutoriels écrits par Nokia Corporation and/or its subsidiary(-ies) inclus dans la documentation de Qt, en anglais. Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia.
II. La classe QDialogButtonBox▲
La classe QDialogButtonBox hérite de QWidget. On peut la remplir avec des boutons, et l'insérer dans le layout d'une boîte de dialogue. Par défaut, les boutons sont affichés horizontalement, mais cela peut être changé en passant Qt::Vertical au constructeur.
En ajoutant des boutons à un QDialogButtonBox, on passe aussi le rôle du bouton, qui spécifie la manière dont il doit être traité.
box->
addButton(tr("OK"
), QDialogButtonBox
::
AcceptRole);
box->
addButton(tr("Cancel"
),QDialogButtonBox
::
RejectRole);
box->
addButton(tr("Apply"
), QDialogButtonBox
::
ApplyRole);
box->
addButton(tr("Reset"
), QDialogButtonBox
::
ResetRole);
box->
addButton(tr("Help"
), QDialogButtonBox
::
HelpRole);
QDialogButtonBox utilise ce rôle pour ordonner les boutons en respectant les conventions de l'environnement graphique de l'utilisateur. Ce tableau explicite les rôles disponibles.
Rôle | Description | Exemples |
---|---|---|
AcceptRole | Acceptation du dialogue | OK, Ouvrir, Sauver, Sauvegarder |
RejectRole | Rejet du dialogue | Annuler, Fermer |
DestructiveRole | Manière risquée de quitter le dialogue | Annuler, Ne pas sauver, Ne pas sauvegarder |
ActionRole | Action sur le dialogue, sans le fermer | Suivant, Plus d'infos |
ResetRole | Opération de réinitialisation | Réinitialiser, Paramètres par défaut |
ApplyRole | Opération semblable aux exemples | Appliquer, Essayer |
HelpRole | Ouvrir l'aide | Aide |
YesRole | Réponse positive | Oui, Oui pour tous |
NoRole | Réponse négative | Non, Non pour tous |
Dès Qt 4.2, cette classe supporte 4 styles : Gnome, KDE, Mac OS X et Windows. L'ordre des boutons est défini par
le style du layout actuel (spécifié par le QStyle actuel)
et par leur rôle. S'il y a plusieurs boutons du même rôle, l'ordre relatif dans lequel ils ont été insérés est
gardé. Ainsi, sous Windows, les boutons sont organisés de cette manière :
Sous Windows et Mac OS X, les rôles YesRole et NoRole sont respectivement équivalents à AcceptRole et à RejectRole.
Sous Mac OS X, l'ordre est normalement le suivant :
Remarquez que le bouton Aide est mis tout à gauche, le bouton Accepter, tout à droite. Ce que le diagramme ne montre pas, c'est que, s'il y a plus d'un bouton Accepter, les boutons supplémentaires sont mis à la gauche du bouton Rejeter, comme cela est indiqué dans le Apple Human Interface Guidelines.
Certains boutons, comme OK, Annuler... reviennent sans cesse dans les boîtes de dialogue. Pour ceux-là, QDialogButtonBox propose une énumération pour faciliter l'opération d'ajout : plus besoin d'un texte ni d'un rôle.
box->
addButton(QDialogButtonBox
::
Ok);
box->
addButton(QDialogButtonBox
::
Cancel);
box->
addButton(QDialogButtonBox
::
Apply);
box->
addButton(QDialogButtonBox
::
Reset);
box->
addButton(QDialogButtonBox
::
Help);
Une alternative à addButton() pour chaque bouton est d'utiliser la propriété standardButtons.
box->
setStandardButtons(QDialogButtonBox
::
Ok
|
QDialogButtonBox
::
Cancel
|
QDialogButtonBox
::
Apply
|
QDialogButtonBox
::
Reset
|
QDialogButtonBox
::
Help);
III. Une boîte de message étendue▲
La classe QMessageBox a été réécrite pour Qt 4.2 afin d'utiliser QDialogButtonBox. L'API a aussi été revisitée afin de supporter les mêmes boutons standard et les mêmes rôles que QDialogButtonBox. Au final, la classe QMessageBox affiche les boutons dans le bon ordre en fonction de l'environnement graphique.
La nouvelle QMessageBox possède une apparence plus native sous Mac OS X, une API qui satisfait les besoins des boîtes de dialogues de plus de trois boutons, ainsi qu'une césure plus sensible.
IV. L'exemple : un éditeur d'emails▲
Nous allons détailler le code d'une classe MailEditor qui utilise QMessageBox et QDialogButtonBox, que voici sous Windows XP et Mac OS X.
Commençons avec le constructeur.
MailEditor::
MailEditor(QWidget
*
parent)
:
QDialog
(parent)
{
...
sendNowButton =
new
QPushButton
(tr("Send Now"
));
...
saveDraftButton =
new
QPushButton
(tr("Save Draft"
));
sendNowButton->
setDefault(true
);
buttonBox =
new
QDialogButtonBox
;
buttonBox->
addButton(sendNowButton,
QDialogButtonBox
::
AcceptRole);
buttonBox->
addButton(discardDraftButton,
QDialogButtonBox
::
DestructiveRole);
buttonBox->
addButton(sendLaterButton,
QDialogButtonBox
::
RejectRole);
buttonBox->
addButton(saveDraftButton,
QDialogButtonBox
::
ActionRole);
QGridLayout
*
layout =
new
QGridLayout
;
...
layout->
addWidget(buttonBox, 3
, 0
, 1
, 2
);
setLayout(layout);
}
Nous instancions les QPushButton comme d'habitude, mais, au lieu de les insérer dans un QHBoxLayout, nous les mettons dans un QDialogButtonBox. Ce tableau liste les boutons, leurs rôles, et les raisons de ce rôle.
Bouton | Rôle | Raison |
---|---|---|
Send Now | AcceptRole | Manière standard de quitter le dialogue |
Discard Draft | DestructiveRole | Fermeture du dialogue avec perte possible de données |
Send Later | RejectRole | Fermeture du dialogue sans envoi du mail |
Save Draft | ActionRole | Pas de fermeture du dialogue |
Dans le slot sendNow(), nous appelons
QDialog::accept() pour fermer le dialogue avec
un résultat d'acceptation.
void
MailEditor::
sendNow()
{
...
accept();
}
Dans discardDraft() et sendLater(), nous appelons QDialog::reject() pour fermer le dialogue avec un résultat de rejet.
void
MailEditor::
discardDraft()
{
...
reject();
}
void
MailEditor::
sendLater()
{
saveDraft();
reject();
}
Le résultat du dialogue est accessible par QDialog::result(). À l'inverse des trois autres slots, saveDraft ne ferme pas le dialogue.
void
MailEditor::
saveDraft()
{
...
textEdit->
document()->
setModified(false
);
}
Si l'utilisateur essaye de fermer le dialogue tant que des changements n'ont pas été enregistrés, nous affichons un dialogue.
void
MailEditor::
closeEvent(QCloseEvent
*
event)
{
if
(textEdit->
document()->
isModified())
{
int
r =
QMessageBox
::
warning(this
,
tr("Mail Editor"
),
tr("Do you want to save the draft "
"before closing?"
),
QMessageBox
::
Save
|
QMessageBox
::
DontSave
|
QMessageBox
::
Cancel);
if
(r ==
QMessageBox
::
Save)
{
saveDraft();
event->
accept();
}
else
if
(r ==
QMessageBox
::
DontSave)
{
event->
accept();
}
else
{
event->
ignore();
}
}
}
Remarquez que nous avons donné des noms explicites aux boutons de la boîte de message (Save, Don't save, Cancel). Pour l'utilisateur, cela risque moins d'amener à des erreurs que des choix plus habituels comme Yes et No.
V. Divers▲
J'adresse ici de chaleureux remerciements à koopajah pour sa relecture orthographique !
Au nom de toute l'équipe Qt, j'aimerais adresser le plus grand remerciement à Nokia pour nous avoir autorisé la traduction de cet article !