Так / ні Поле повідомлень за допомогою QMessageBox


108

Як відобразити вікно повідомлень із кнопками Так / Ні в Qt, і як перевірити, яка з них була натиснута?

Тобто вікно повідомлень, яке виглядає приблизно так:

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

Відповіді:


184

Ви б використали 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 += consoleWin32, щоб побачити qDebug()вихід.

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


У мене виникає питання щодо того, як ви динамічно генеруєте поле для повідомлень: чи краще це зробити так або заздалегідь визначити все (створити та зберігати поле для змін у змінній тощо), а потім просто зателефонувати за потреби?
rbaleksandar

1
@rbaleksandar Краще використовувати статичні методи QMessageBox. Qt очистить будь-яку пам'ять, використану при поверненні методів, немає необхідності постійно зберігати її в пам'яті.
JoshL

Дякую, це має сенс. Адже ця частина користувальницького інтерфейсу - це не те, що 1) вимагає багато ресурсів, тому потрібен певний час для завантаження і 2) часто або навіть постійно на екрані, щоб користувач його бачив.
rbaleksandar

Найкраща відповідь коли-небудь.
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
}

Цікава відповідь, як би ви додали до нього значок? Як інформація?
Даріуш

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()) 
{

}

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>


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_()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.