2012-09-18 7 views
14

Ich habe Unterklasse, um Funktionalität ähnlich QMessageBox zu implementieren (ich brauchte dies für die Anpassung zu ermöglichen). Es hat eine Textnachricht und OK, Abbrechen-Tasten. Ich zeige den Dialog mit exec(), um es zu blockieren. Wie gebe ich nun Werte von "Wahr/Falsch" zurück, wenn der Benutzer auf "OK/Abbrechen" klickt?QDialog exec() und bekommen Ergebniswert

Ich habe versucht, um die Tasten zu setResult() verbinden und dann, geben den Wert Ergebnis, wenn geklickt, aber 1. Anklicken des Buttons 2. den Wert Rückkehr wird das Dialogfeld falsch nicht schließen. Folgendes ist der Code, den ich geschrieben habe. Ich denke, ich liege falsch im exec/Ergebnis Teil - aber ich bin mir nicht sicher, wie ich es beheben soll.

class MyMessageBox : public QDialog 
{ 
    Q_OBJECT 

private slots: 

    void onOKButtonClicked(){ this->setResult(QDialog::Accepted);} 
    void onCancelButtonClicked(){ this->setResult(QDialog::Rejected);} 

public: 

    MyMessageBox(QMessageBox::Icon icon, const QString & title, const QString & text, bool showCancelButton = true, QWidget *parent = 0); 

    virtual void resizeEvent(QResizeEvent* e); 

     QDialog::DialogCode showYourself() 
     { 
      this->setWindowModality(Qt::ApplicationModal); 
      this->exec(); 
      return static_cast<QDialog::DialogCode>(this->result()); 
     } 

    }; 

Der Benutzer wird die Klasse instanziiert und rufen showYourself(), die den Wert zurückgeben wird erwartet, und auch in der Nähe (und löschen), um den Dialog.

Ich habe Teilcode veröffentlicht. Lass es mich wissen, wenn du mehr brauchst und ich werde die komplette Version veröffentlichen.

Antwort

15

Einige Punkte:

  1. Anstatt setResult() selbst mit, QDialog::accept() und QDialog::reject() verwenden.
  2. Es scheint, dass Sie die Signale und Slots nicht voll ausnutzen. Sie benötigen das Objekt, das den Dialog erstellt (oder einen anderen), um die Signale des Dialogs zu hören.
  3. In Ihrem Code verbinden Sie auch keine Signale mit Slots.
  4. Mit meinem Fix onOKButtonClicked und onCancelButtonClicked sind unnötig.
  5. Mit meinem Fix brauchen Sie nicht showYourself(). Rufen Sie einfach exec und mit den Ereignissen Informationen fließen.

Sie müssen diesen Code hinzufügen, bevor Sie den Dialog zeigt (this annehmen, dass es in einem Dialogverfahren ist):

QObject::connect(acceptButton, SIGNAL(clicked()), this, SLOT(accept())); 
QObject::connect(rejectButton, SIGNAL(clicked()), this, SLOT(reject())); 

Im Aufruferobjekt Sie

void someInitFunctionOrConstructor(){ 
    QObject::connect(mydialog, SIGNAL(finished (int)), this, SLOT(dialogIsFinished(int))); 
} 

void dialogIsFinished(int){ //this is a slot 
    if(result == QDialog::Accepted){ 
     //do something 
     return 
    } 
    //do another thing 
} 
+0

Vielen Dank! Das ist aufschlussreich. Wenn ich das mache, muss ich das Objekt explizit löschen oder wird es intern erledigt? – go4sri

+0

Wenn das Objekt ein Elternelement hat, wird es gelöscht, wenn das Elternelement gelöscht wird. Sie können 'QObject :: deleteLater()' verwenden, um einen Löschvorgang zu planen. Wenn Sie sicher sind, dass ein Objekt nicht mehr verwendet wird (kein Ereignis, das mit diesem Objekt in Verbindung steht), können Sie das gute alte Löschen verwenden. – UmNyobe

+0

sehr gute Antwort! Danke! – Victor

8

Fall 1 Durch Klicken auf die Schaltflächen wird das Dialogfeld nicht geschlossen.

Dazu geben Sie den Dialog auf entsprechenden SLOTS schließen müssen, so verwenden

void onOKButtonClicked(){ this->setResult(QDialog::Accepted); this->close();} 
void onCancelButtonClicked(){ this->setResult(QDialog::Rejected);this->close();} 

Hinweis: Erst wenn Sie auf die Schaltfläche OK geklickt haben, oder Abbrechen-Taste in einem Standard-QMessageBox wird setResult() Funktion ausgelöst und der Status wird geändert. Es ist nicht der gleiche Effekt, wenn umgekehrt.

Fall 2 Der Rückgabewert ist falsch.

Ich denke, erst nachdem Ihr Dialog geschlossen wird, haben Sie das Ergebnis in result() Funktion verfügbar. Ich denke, es wird gelöst werden, nachdem Sie die Änderungen in Fall 1 vorgenommen haben.

Wenn es weiterhin besteht, verwenden Sie Ihre eigene private Member-Funktion, um es zu beheben.

+0

Vielen Dank. das funktioniert. – go4sri

+4

Aufruf this -> close() nach dem Setzen dieser -> setResult (QDialog :: Accepted); wird dazu führen, dass das Ergebnis am Ende 0 anstatt 1 ist. So rufen Sie die setResult() nach dem Schließen() – ManuelH

14

Eine andere Lösung haben:

// set signal and slot for "Buttons" 
    connect(YesButton, SIGNAL(clicked()), dlg, SLOT(accept())); 
    connect(NoButton, SIGNAL(clicked()), dlg, SLOT(reject())); 

    // show modal window event loop and wait for button clicks 
    int dialogCode = dlg->exec(); 

    // act on dialog return code 
    if(dialogCode == QDialog::Accepted) { // YesButton clicked } 
    if(dialogCode == QDialog::Rejected) { // NoButton clicked }