Okno komunikatu Tak / Nie używające QMessageBox

108

Jak wyświetlić okno komunikatu z przyciskami Tak / Nie w Qt i jak sprawdzić, który z nich został naciśnięty?

To znaczy okno komunikatu, które wygląda następująco:

wprowadź opis obrazu tutaj

sashoalm
źródło

Odpowiedzi:

184

Używałbyś QMessageBox::questiondo tego.

Przykład w slocie hipotetycznego widżetu:

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

Powinien działać na Qt 4 i 5, wymaga QT += widgetsQt 5 i CONFIG += consoleWin32, aby zobaczyć qDebug()wyjście.

Zobacz StandardButtonwyliczenie, aby uzyskać listę przycisków, których możesz użyć; funkcja zwraca przycisk, który został kliknięty. Możesz ustawić przycisk domyślny z dodatkowym argumentem (Qt "automatycznie wybiera odpowiednią wartość domyślną ", jeśli tego nie zrobisz lub nie określisz QMessageBox::NoButton).

Mata
źródło
Mam pytanie dotyczące sposobu, w jaki dynamicznie generujesz okno komunikatu: czy lepiej jest to zrobić w ten sposób, czy wstępnie zdefiniować całość (utworzyć i przechowywać okno komunikatu w zmiennej itp.), A następnie po prostu wywołać to w razie potrzeby?
rbaleksandar
1
@rbaleksandar Lepiej jest używać statycznych metod QMessageBox. Qt wyczyści pamięć używaną po powrocie metod, nie ma potrzeby utrzymywania pamięci na stałe.
JoshL
Dzięki, to ma sens. W końcu ta część interfejsu użytkownika nie jest czymś, co 1) wymaga dużej ilości zasobów, więc ładowanie zajmuje trochę czasu i 2) jest często lub nawet stale widoczne na ekranie, aby użytkownik mógł ją zobaczyć.
rbaleksandar
Najlepsza odpowiedź w historii.
GeneCode
41

Możesz użyć obiektu QMessage, aby utworzyć skrzynkę wiadomości, a następnie dodać przyciski:

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
źródło
Ciekawa odpowiedź, jak dodałbyś do niego ikonę? Jak informacje?
Dariusz
1
@Dariusz: masz setIconczęść metody QMessageBoxobiektu. z jednym, jeśli te QMessageBox::NoIcon QMessageBox::Question QMessageBox::Information wyliczenia
rednaks
19

QT może być tak proste, jak w systemie Windows. Odpowiedni kod to

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

}
hkyi
źródło
5

W odpowiedziach brakuje mi wezwania do tłumaczenia tr.

Jedno z najprostszych rozwiązań, które pozwala na późniejszą internacjonalizację:

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

Ogólnie dobrym Qtzwyczajem jest umieszczanie w tr("Your String")wywołaniu ciągów znaków na poziomie kodu .

( QMessageboxjak wyżej działa w ramach dowolnej QWidgetmetody)

EDYTOWAĆ:

możesz używać QMesssageBoxpoza QWidgetkontekstem, zobacz odpowiedź @ TobySpeight.

Jeśli jesteś nawet poza QObjectkontekście wymienić trz qApp->translate("context", "String")- trzeba#include <QApplication>

DomTomCat
źródło
4

QMessageBox zawiera statyczne metody szybkiego zadawania takich pytań:

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

Jeśli Twoje potrzeby są bardziej złożone niż przewidują to metody statyczne, powinieneś skonstruować nowy QMessageBoxobiekt i wywołać jego exec()metodę, aby pokazać go we własnej pętli zdarzeń i uzyskać identyfikator wciśniętego przycisku. Na przykład możemy chcieć, aby domyślną odpowiedzią było „Nie”:

#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
źródło
2
Ponieważ już QApplicationqApp->translate("context", "String")trQObject
włączyłeś
-2

Jeśli chcesz zrobić to w Pythonie, musisz sprawdzić ten kod w swoim środowisku roboczym. też pisz w ten sposób. stworzyliśmy wyskakujące okienko w Pythonie.

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
źródło