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í

sashoalm
fuente

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).

Estera
fuente
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
}
rednaks
fuente
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()) 
{

}
hkyi
fuente
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>

DomTomCat
fuente
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
        ;
}
Toby Speight
fuente
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_()
Rajendra Prasad Taidala
fuente