Окно сообщения Да / Нет с использованием QMessageBox

110

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

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

введите описание изображения здесь

сашоальм
источник

Ответы:

186

Вы бы использовали 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).

Мат
источник
У меня вопрос относительно того, как вы динамически генерируете окно сообщения: что лучше сделать так, или предопределить все это (создать и сохранить окно сообщения в переменной и т. Д.), А затем просто вызвать его при необходимости?
rbaleksandar
1
@rbaleksandar Лучше использовать статические методы QMessageBox. Qt очистит любую используемую память, когда методы вернутся, нет необходимости держать ее в памяти постоянно.
JoshL 05
Спасибо, это имеет смысл. В конце концов, эта часть пользовательского интерфейса не является чем-то, что: 1) требует много ресурсов, поэтому требуется некоторое время для загрузки и 2) часто или даже постоянно отображается на экране, чтобы пользователь мог ее увидеть.
rbaleksandar 05
Лучший ответ на свете.
GeneCode
41

Вы можете использовать объект 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
}
Rednaks
источник
Интересный ответ, а как бы к нему добавить иконку? Нравится информация?
Dariusz
1
@Dariusz: у вас есть setIconметодическая часть QMessageBoxобъекта. с одним, если эти перечисления в качестве параметров: QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop
rednaks
19

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

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

}
hkyi
источник
5

В 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>

DomTomCat
источник
4

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
        ;
}
Тоби Спейт
источник
2
Поскольку вы уже включили, QApplicationя предлагаю использовать qApp->translate("context", "String"), который заменяет trиспользование вне QObjectкласса
DomTomCat
-2

Если вы хотите сделать это на Python, вам нужно проверить этот код на своем рабочем месте. тоже напиши вот так. мы создали всплывающее окно с помощью Python.

msgBox = QMessageBox()
msgBox.setText("The document has been modified.")
msgBox.setInformativeText("Do you want to save your changes?")
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
msgBox.setDefaultButton(QMessageBox.Save)
ret = msgBox.exec_()
Раджендра Прасад Тайдала
источник