Cuadro de mensaje Sí / No usando QMessageBox


108

¿Cómo muestro un cuadro de mensaje con botones Sí / No en Qt y cómo verifico cuál de ellos se presionó?

Es decir, un cuadro de mensaje que se ve así:

ingrese la descripción de la imagen aquí

Respuestas:


184

Lo usarías QMessageBox::questionpara eso.

Ejemplo en la ranura de un 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";
  }
}

Debería funcionar en Qt 4 y 5, requiere QT += widgetsen Qt 5 y CONFIG += consoleen Win32 para ver la qDebug()salida.

Consulte la StandardButtonenumeración para obtener una lista de botones que puede usar; la función devuelve el botón en el que se hizo clic. Puede establecer un botón predeterminado con un argumento adicional (Qt " elige automáticamente un botón predeterminado adecuado " si no lo especifica QMessageBox::NoButton).


Tengo una pregunta sobre la forma en que genera dinámicamente el cuadro de mensaje: ¿es mejor hacerlo así o predefinir todo (crear y almacenar el cuadro de mensaje en una variable, etc.) y luego simplemente llamarlo cuando sea necesario?
— rbaleksandar

1
@rbaleksandar Es mejor usar los métodos estáticos QMessageBox. Qt limpiará cualquier memoria utilizada cuando los métodos regresen, no es necesario mantener una en la memoria de forma permanente.
— JoshL

Gracias, tiene sentido. Después de todo, esta parte de la interfaz de usuario no es algo que 1) requiera muchos recursos, por lo que lleva algo de tiempo cargarse y 2) está a menudo o incluso constantemente en la pantalla para que el usuario la vea.
— rbaleksandar

La mejor respuesta de todas.
— GeneCode

41

Puede usar el objeto QMessage para crear un cuadro de mensaje y luego agregar botones:

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
}

Interesante respuesta, ¿cómo le agregarías un ícono? ¿Te gusta la información?
— Dariusz

1
@Dariusz: tienes el setIconmétodo como parte del QMessageBoxobjeto. con uno si estas enumeraciones como parámetros: QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop
— rednaks

19

QT puede ser tan simple como el de Windows. El código equivalente es

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

}

5

Me falta la llamada de traducción tren las respuestas.

Una de las soluciones más sencillas, que permite una posterior internacionalización:

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

En general, es un buen Qthábito colocar cadenas a nivel de código dentro de una tr("Your String")llamada.

( QMessageboxcomo arriba funciona dentro de cualquier QWidgetmétodo)

EDITAR:

puede usar QMesssageBoxfuera de un QWidgetcontexto, consulte la respuesta de @ TobySpeight.

Incluso si está fuera de un QObjectcontexto, reemplace trcon qApp->translate("context", "String")- necesitará#include <QApplication>


4

QMessageBox incluye métodos estáticos para hacer rápidamente tales preguntas:

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

Si sus necesidades son más complejas que las previstas por los métodos estáticos, debe construir un nuevo QMessageBoxobjeto y llamar a su exec()método para mostrarlo en su propio bucle de eventos y obtener el identificador del botón presionado. Por ejemplo, podríamos querer que "No" sea la respuesta predeterminada:

#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
Como ya lo incluyó QApplication, sugiero usar qApp->translate("context", "String"), que reemplaza trpara el uso fuera de una QObjectclase
— DomTomCat

-2

Si desea hacerlo en Python, debe verificar este código en su banco de trabajo. también escribe así. Creamos un cuadro emergente con 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_()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.