Casella di messaggio Sì / No utilizzando QMessageBox


108

Come faccio a visualizzare una finestra di messaggio con i pulsanti Sì / No in Qt e come faccio a verificare quale di essi è stato premuto?

Cioè una finestra di messaggio che assomiglia a questa:

inserisci qui la descrizione dell'immagine

Risposte:


184

Lo useresti QMessageBox::questionper quello.

Esempio nello slot di un ipotetico widget:

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

Dovrebbe funzionare su Qt 4 e 5, richiede QT += widgetssu Qt 5 e CONFIG += consolesu Win32 per vedere l' qDebug()output.

Vedere l' StandardButtonenumerazione per ottenere un elenco di pulsanti che è possibile utilizzare; la funzione restituisce il pulsante che è stato cliccato. Puoi impostare un pulsante predefinito con un argomento extra (Qt " sceglie automaticamente un valore predefinito adatto " se non lo fai o lo specifichi QMessageBox::NoButton).


Ho una domanda sul modo in cui generi dinamicamente la finestra di messaggio: è meglio farlo in questo modo o predefinire il tutto (creare e memorizzare la finestra di messaggio in una variabile, ecc.) E poi chiamarla semplicemente quando necessario?
rbaleksandar

1
@rbaleksandar È meglio usare i metodi statici di QMessageBox. Qt ripulirà tutta la memoria utilizzata quando i metodi tornano, non è necessario tenerne uno in memoria in modo permanente.
JoshL,

Grazie, ha senso. Dopotutto questa parte dell'interfaccia utente non è qualcosa che 1) richiede molte risorse quindi richiede un po 'di tempo per caricarsi e 2) è spesso o addirittura costantemente sullo schermo affinché l'utente possa vederlo.
rbaleksandar

La migliore risposta in assoluto.
GeneCode

41

È possibile utilizzare l'oggetto QMessage per creare una finestra di messaggio, quindi aggiungere i pulsanti:

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
}

Risposta interessante, come aggiungeresti un'icona? Ti piacciono le informazioni?
Dariusz

1
@ Dariusz: hai la setIconparte metodo QMessageBoxdell'oggetto. con uno se queste enumerazioni come parametri: QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop
rednaks

19

QT può essere semplice come quello di Windows. Il codice equivalente è

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

}

5

Mi manca la chiamata di traduzione trnelle risposte.

Una delle soluzioni più semplici, che consente una successiva internazionalizzazione:

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

È generalmente una buona Qtabitudine inserire stringhe a livello di codice all'interno di una tr("Your String")chiamata.

( QMessageboxcome sopra funziona con qualsiasi QWidgetmetodo)

MODIFICARE:

puoi usare QMesssageBoxal di fuori di un QWidgetcontesto, vedi la risposta di @ TobySpeight.

Se sei anche al di fuori di un QObjectcontesto, sostituisci trcon qApp->translate("context", "String")- dovrai#include <QApplication>


4

QMessageBox include metodi statici per porre rapidamente tali domande:

#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 le tue esigenze sono più complesse di quanto previsto dai metodi statici, dovresti costruire un nuovo QMessageBoxoggetto e chiamare il suo exec()metodo per mostrarlo nel suo ciclo di eventi e ottenere l'identificatore del pulsante premuto. Ad esempio, potremmo voler impostare "No" come risposta predefinita:

#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
Dato che hai già incluso, QApplicationti suggerisco di utilizzare qApp->translate("context", "String"), che sostituisce trl'uso al di fuori di una QObjectclasse
DomTomCat

-2

Se vuoi farlo in Python devi controllare questo codice nel tuo workbench. scrivi anche così. abbiamo creato una finestra popup 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_()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.