IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Réordonner les boutons

Image non disponible

Les différentes plateformes supportées par Qt ont des lignes directrices différentes pour l'ordre des boutons dans les boîtes de dialogue. La différence la plus visible est l'inversion des boutons OK et Annuler sous Mac OS X et Gnome, mais il y a bien d'autres différences. Pour s'assurer que les boîtes de dialogue créées avec Qt Designer aient un air natif sur toutes les plateformes, Qt 4.2 introduit la classe QDialogButtonBox, une couche d'abstraction de la ligne de boutons, généralement en bas ou à droite.

Cet article est une traduction autorisée de Reordering OK and Cancel.

14 commentaires Donner une note à l´article (5)

Article lu   fois.

Les deux auteurs

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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.

Image non disponible
Image non disponible

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

 
Sélectionnez
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 :

Image non disponible

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 :

Image non disponible

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.

 
Sélectionnez
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.

 
Sélectionnez
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.

Image non disponible
Image non disponible

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.

Image non disponible
Image non disponible

Commençons avec le constructeur.

 
Sélectionnez
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.

 
Sélectionnez
void MailEditor::sendNow()
{
    ...
    accept();
}

Dans discardDraft() et sendLater(), nous appelons QDialog::reject() pour fermer le dialogue avec un résultat de rejet.

 
Sélectionnez
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.

 
Sélectionnez
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.

 
Sélectionnez
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 !

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2006 Nokia Corporation and/or its subsidiary(-ies). Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.