133 votes

Boîte de message Oui/Non utilisant QMessageBox

Comment afficher une boîte de message avec des boutons Oui/Non en Qt, et comment vérifier lequel d'entre eux a été pressé ?

Par exemple, une boîte de message qui ressemble à ceci :

description de l'image

215voto

Mat Points 104488

Vous utiliseriez QMessageBox::question pour cela.

Exemple dans un slot hypothétique d'un widget :

#include 
#include 
#include 

// ...

void MyWidget::someSlot() {
  QMessageBox::StandardButton reply;
  reply = QMessageBox::question(this, "Test", "Quit?",
                                QMessageBox::Yes|QMessageBox::No);
  if (reply == QMessageBox::Yes) {
    qDebug() << "Yes was clicked";
    QApplication::quit();
  } else {
    qDebug() << "Yes was *not* clicked";
  }
}

Devrait fonctionner sur Qt 4 et 5, nécessite <code>QT += widgets</code> sur Qt 5, et <code>CONFIG += console</code> sur Win32 pour voir la sortie de <code>qDebug()</code>.

Voir l' StandardButton enum pour obtenir une liste de boutons que vous pouvez utiliser ; la fonction renvoie le bouton qui a été cliqué. Vous pouvez définir un bouton par défaut avec un argument supplémentaire (Qt "choisit automatiquement un bouton par défaut adapté" si vous ne le spécifiez pas ou spécifiez QMessageBox::NoButton).

0 votes

J'ai une question concernant la façon dont vous générez dynamiquement la boîte de message : est-il préférable de le faire ainsi ou de prédéfinir l'ensemble (créer et stocker la boîte de message dans une variable, etc.) puis simplement l'appeler quand nécessaire ?

1 votes

@rbaleksandar Il vaut mieux utiliser les méthodes statiques de QMessageBox. Qt va nettoyer toute la mémoire utilisée lorsque les méthodes retournent, il n'est pas nécessaire d'en conserver une en mémoire de façon permanente.

0 votes

Merci, cela a du sens. Après tout, cette partie de l'interface utilisateur n'est pas quelque chose qui 1) nécessite beaucoup de ressources et qui prend donc du temps pour se charger et 2) est souvent, voire constamment, à l'écran pour que l'utilisateur puisse la voir.

48voto

rednaks Points 425

Vous pouvez utiliser l'objet QMessage pour créer une boîte de message puis ajouter des boutons :

QMessageBox msgBox;
msgBox.setWindowTitle("titre");
msgBox.setText("Question");
msgBox.setStandardButtons(QMessageBox::Yes);
msgBox.addButton(QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No);
if(msgBox.exec() == QMessageBox::Yes){
  // faire quelque chose
}else {
  // faire quelque chose d'autre
}

0 votes

Réponse intéressante, comment ajouteriez-vous une icône à celle-ci? Comme Information?

1 votes

@Dariusz: vous avez la méthode setIcon faisant partie de l'objet QMessageBox, avec l'un de ces énumérations en tant que paramètres : QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop

22voto

hkyi Points 154

QT peut être aussi simple que celui de Windows. Le code équivalent est

if (QMessageBox::Yes == QMessageBox(QMessageBox::Information, "titre", "Question", QMessageBox::Yes|QMessageBox::No).exec()) 
{

}

7voto

DomTomCat Points 3719

Je manque d'appeler la traduction tr dans les réponses.

Une des solutions les plus simples, qui permet une internationalisation ultérieure :

if (QMessageBox::Yes == QMessageBox::question(this,
                                              tr("titre"),
                                              tr("Message/Question")))
{
    // faire des trucs
}

C'est généralement une bonne habitude en Qt de placer les chaînes au niveau du code dans un appel tr("Votre Chaîne").

(QMessagebox comme ci-dessus fonctionne dans n'importe quelle méthode QWidget)

EDIT :

Vous pouvez utiliser QMessageBox en dehors d'un contexte QWidget, voir la réponse de @TobySpeight.

Si vous êtes même en dehors d'un contexte QObject, remplacez tr par qApp->translate("contexte", "Chaîne") - vous devrez #include

4voto

Toby Speight Points 3930

QMessageBox inclut des méthodes statiques pour poser rapidement de telles questions :

#include 
#include 

int main(int argc, char **argv)
{
    QApplication app{argc, argv};
    while (QMessageBox::question(nullptr,
                                 qApp->translate("my_app", "Test"),
                                 qApp->translate("my_app", "Are you sure you want to quit?"),
                                 QMessageBox::Yes|QMessageBox::No)
           != QMessageBox::Yes)
        // poser à nouveau la question
        ;
}

Si vos besoins sont plus complexes que ce que proposent les méthodes statiques, vous devriez construire un nouvel objet QMessageBox et appeler sa méthode exec() pour l'afficher dans sa propre boucle d'événements et obtenir l'identifiant du bouton appuyé. Par exemple, nous pourrions vouloir faire de "Non" la réponse par défaut :

#include 
#include 

int main(int argc, char **argv)
{
    QApplication app{argc, argv};
    auto question = new QMessageBox(QMessageBox::Question,
                                    qApp->translate("my_app", "Test"),
                                    qApp->translate("my_app", "Are you sure you want to quit?"),
                                    QMessageBox::Yes|QMessageBox::No,
                                    nullptr);
    question->setDefaultButton(QMessageBox::No);

    while (question->exec() != QMessageBox::Yes)
        // poser à nouveau la question
        ;
}

2 votes

Depuis que vous avez déjà inclus QApplication, je vous suggère d'utiliser qApp->translate("context", "String"), qui remplace tr pour une utilisation en dehors d'une classe QObject.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X