Ja / Nein-Meldungsfeld mit QMessageBox


108

Wie zeige ich in Qt ein Meldungsfeld mit Ja / Nein-Schaltflächen an und wie überprüfe ich, welche davon gedrückt wurde?

Dh ein Meldungsfeld, das so aussieht:

Geben Sie hier die Bildbeschreibung ein

Antworten:


184

Sie würden dafür verwenden QMessageBox::question.

Beispiel im Slot eines hypothetischen Widgets:

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

Sollte auf Qt 4 und 5 funktionieren, erfordert QT += widgetsauf Qt 5 und CONFIG += consoleauf Win32, um die qDebug()Ausgabe zu sehen .

In der StandardButtonAufzählung finden Sie eine Liste der Schaltflächen, die Sie verwenden können. Die Funktion gibt die Schaltfläche zurück, auf die geklickt wurde. Sie können eine Standardschaltfläche mit einem zusätzlichen Argument festlegen (Qt " wählt automatisch einen geeigneten Standard aus ", wenn Sie dies nicht tun oder angeben QMessageBox::NoButton).


Ich habe eine Frage zur Art und Weise, wie Sie das Nachrichtenfeld dynamisch generieren: Ist es besser, dies so zu tun oder das Ganze vordefinieren (das Nachrichtenfeld in einer Variablen erstellen und speichern usw.) und es dann bei Bedarf einfach aufzurufen?
Rbaleksandar

1
@rbaleksandar Es ist besser, die statischen QMessageBox-Methoden zu verwenden. Qt bereinigt jeden Speicher, der bei der Rückkehr der Methoden verwendet wird. Es ist nicht erforderlich, einen dauerhaft im Speicher zu halten.
JoshL

Danke, es macht Sinn. Schließlich ist dieser Teil der Benutzeroberfläche nicht etwas, das 1) viele Ressourcen erfordert, daher einige Zeit zum Laden benötigt und 2) häufig oder sogar ständig auf dem Bildschirm angezeigt wird, damit der Benutzer ihn sehen kann.
Rbaleksandar

Beste Antwort aller Zeiten.
GeneCode

41

Mit dem QMessage-Objekt können Sie ein Nachrichtenfeld erstellen und dann Schaltflächen hinzufügen:

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
}

Interessante Antwort, wie würden Sie ein Symbol hinzufügen? Gefällt mir Informationen?
Dariusz

1
@Dariusz: Sie haben den setIconMethodenteil des QMessageBoxObjekts. mit einer, wenn diese Aufzählungen als Parameter: QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information doc.qt.io/qt-4.8/qmessagebox.html#icon-prop
rednaks

19

QT kann so einfach sein wie Windows. Der entsprechende Code lautet

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

}

5

Ich vermisse den Übersetzungsaufruf trin den Antworten.

Eine der einfachsten Lösungen, die eine spätere Internationalisierung ermöglicht:

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

Es ist im Allgemeinen eine gute QtAngewohnheit, Strings auf Codeebene in einen tr("Your String")Aufruf einzufügen.

( QMessageboxwie oben funktioniert innerhalb jeder QWidgetMethode)

BEARBEITEN:

Sie können QMesssageBoxaußerhalb eines QWidgetKontexts verwenden, siehe die Antwort von @ TobySpeight.

Wenn Sie sich sogar außerhalb eines QObjectKontexts befinden, ersetzen Sie ihn trdurch qApp->translate("context", "String")- Sie müssen#include <QApplication>


4

QMessageBox enthält statische Methoden, um solche Fragen schnell zu stellen:

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

Wenn Ihre Anforderungen komplexer sind als von den statischen Methoden vorgesehen, sollten Sie ein neues QMessageBoxObjekt erstellen und seine exec()Methode aufrufen , um es in einer eigenen Ereignisschleife anzuzeigen und die Kennung der gedrückten Schaltfläche zu erhalten. Zum Beispiel möchten wir vielleicht "Nein" als Standardantwort festlegen:

#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
Da Sie bereits aufgenommen haben, QApplicationwürde ich die Verwendung vorschlagen qApp->translate("context", "String"), die trdie Verwendung außerhalb einer QObjectKlasse ersetzt
DomTomCat

-2

Wenn Sie es in Python schaffen möchten, müssen Sie diesen Code in Ihrer Workbench überprüfen. schreibe auch so. Wir haben ein Popup-Feld mit Python erstellt.

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_()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.