Да/Нет окна сообщений с помощью QMessageBox

Как показать окно сообщения с кнопками Да/Нет в Qt и как проверить, какие из них были нажаты?

т.е. окно сообщения, которое выглядит так:

enter image description here

Ответ 1

Вы использовали бы QMessageBox::question.

Пример в гипотетическом слоте виджета:

#include <QApplication>
#include <QMessageBox>
#include <QDebug>

// ...

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";
  }
}

Должно работать в Qt 4 и 5, требуется QT += widgets на Qt 5 и CONFIG += console на Win32, чтобы увидеть вывод qDebug().

Перейдите в список StandardButton, чтобы получить список кнопок, которые вы можете использовать; функция возвращает кнопку, на которую была нажата кнопка. Вы можете установить кнопку по умолчанию с дополнительным аргументом (Qt "автоматически выбирает подходящее значение по умолчанию", если вы не указали или не указали QMessageBox::NoButton).

Ответ 2

Вы можете использовать объект QMessage для создания окна сообщений, а затем добавить кнопки:

QMessageBox msgBox;
msgBox.setWindowTitle("title");
msgBox.setText("Question");
msgBox.setStandardButtons(QMessageBox::Yes);
msgBox.addButton(QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No);
if(msgBox.exec() == QMessageBox::Yes){
  // do something
}else {
  // do something else
}

Ответ 3

QT может быть таким же простым, как у Windows. Эквивалентный код

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

}

Ответ 4

Мне не хватает перевода tr в ответах.

Одно из самых простых решений, которое позволяет более позднюю интернационализацию:

if (QMessageBox::Yes == QMessageBox::question(this,
                                              tr("title"),
                                              tr("Message/Question")))
{
    // do stuff
}

Обычно хорошая Qt привычка размещать строки уровня кода внутри вызова tr("Your String").

(QMessagebox, как указано выше, работает в рамках любого метода QWidget)

ИЗМЕНИТЬ:

вы можете использовать QMesssageBox вне контекста QWidget, см. ответ @TobySpeight.

Если вы даже вне контекста QObject, замените tr на qApp->translate("context", "String") - вам нужно #include <QApplication>

Ответ 5

QMessageBox включает статические методы, чтобы быстро задать такие вопросы:

#include <QApplication>
#include <QMessageBox>

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)
        // ask again
        ;
}

Если ваши потребности более сложны, чем предусмотрены статическими методами, вы должны создать новый объект QMessageBox и вызвать его метод exec(), чтобы показать его в своем собственном цикле событий и получить идентификатор нажатой кнопки. Например, мы могли бы сделать "Нет" ответом по умолчанию:

#include <QApplication>
#include <QMessageBox>

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)
        // ask again
        ;
}