Sim / Não caixa de mensagem usando QMessageBox

108

Como faço para mostrar uma caixa de mensagem com botões Sim / Não no Qt, e como eu verifico qual deles foi pressionado?

Ou seja, uma caixa de mensagem semelhante a esta:

insira a descrição da imagem aqui

sashoalm
fonte

Respostas:

184

Você usaria QMessageBox::questionpara isso.

Exemplo em um slot de widget hipotético:

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

Deve funcionar no Qt 4 e 5, requer QT += widgetsno Qt 5 e CONFIG += consoleno Win32 para ver a qDebug()saída.

Consulte o StandardButtonenum para obter uma lista de botões que você pode usar; a função retorna o botão que foi clicado. Você pode definir um botão padrão com um argumento extra (Qt " escolhe um padrão adequado automaticamente " se você não escolher ou especificar QMessageBox::NoButton).

Esteira
fonte
Eu tenho uma pergunta sobre a maneira como você gera dinamicamente a caixa de mensagem: é melhor fazer assim ou predefinir tudo (criar e armazenar a caixa de mensagem em uma variável etc.) e simplesmente chamá-la quando necessário?
rbaleksandar
1
@rbaleksandar É melhor usar os métodos estáticos QMessageBox. Qt irá limpar qualquer memória usada quando os métodos retornarem, não há necessidade de manter uma memória permanentemente.
JoshL
Obrigado, faz sentido. Afinal, essa parte da IU não é algo que 1) requer muitos recursos, portanto, leva algum tempo para carregar e 2) está frequentemente ou mesmo constantemente na tela para que o usuário veja.
rbaleksandar
Melhor resposta de todas.
GeneCode
41

Você pode usar o objeto QMessage para criar uma caixa de mensagem e adicionar botões:

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
fonte
Resposta interessante, como você adicionaria um ícone a ele? Gosta de informações?
Dariusz
1
@Dariusz: você tem a setIconparte do método do QMessageBoxobjeto. com um destes enums como parâmetros: QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop
rednaks
19

O QT pode ser tão simples quanto o do Windows. O código equivalente é

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

}
Hkyi
fonte
5

Estou perdendo a chamada de tradução trnas respostas.

Uma das soluções mais simples, que permite uma posterior internacionalização:

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

Geralmente, é um bom Qthábito colocar Strings de nível de código em uma tr("Your String")chamada.

( QMessageboxcomo acima funciona em qualquer QWidgetmétodo)

EDITAR:

você pode usar QMesssageBoxfora de um QWidgetcontexto, consulte a resposta de @TobySpeight.

Se você estiver fora de um QObjectcontexto, substitua trpor qApp->translate("context", "String")- você precisará#include <QApplication>

DomTomCat
fonte
4

QMessageBox inclui métodos estáticos para fazer rapidamente essas perguntas:

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

Se suas necessidades são mais complexas do que as fornecidas pelos métodos estáticos, você deve construir um novo QMessageBoxobjeto e chamar seu exec()método para mostrá-lo em seu próprio loop de eventos e obter o identificador do botão pressionado. Por exemplo, podemos querer que "Não" seja a resposta padrão:

#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
        ;
}
Toby Speight
fonte
2
Como você já incluiu QApplication, sugiro usar qApp->translate("context", "String"), que substitui tro uso fora de uma QObjectclasse
DomTomCat
-2

Se você quiser fazer em python, você precisa verificar este código em seu ambiente de trabalho. também escreva assim. criamos uma caixa pop-up com 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_()
Rajendra Prasad Taidala
fonte