2012-09-18 14 views
14

Ho implementato la sottoclasse QDialog per implementare funzionalità simili a QMessageBox (ne avevo bisogno per consentire la personalizzazione). Ha un messaggio di testo e OK, pulsanti Annulla. Sto mostrando la finestra di dialogo usando exec() per bloccarlo. Ora, come posso restituire i valori di vero/falso quando l'utente fa clic su OK/Annulla?QDialog exec() e ottenere il valore del risultato

Ho cercato di collegare i pulsanti per setResult() e poi, riportare il valore del risultato quando si fa clic, ma 1. Facendo clic sui pulsanti non chiude la finestra di dialogo 2. il valore restituito non è corretto. Di seguito è riportato il codice che ho scritto. Penso di sbagliarmi nella parte exec/result - ma non sono sicuro di come risolverlo.

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()); 
     } 

    }; 

L'utente potrà creare un'istanza della classe e chiamare showYourself() che dovrebbe restituire il valore e anche vicino (e cancellare) la finestra di dialogo.

Ho inserito il codice parziale. Fatemi sapere se avete bisogno di più e pubblicherò la versione completa.

risposta

15

Alcuni punti:

  1. Piuttosto che usare setResult() te, utilizzare QDialog::accept() e QDialog::reject().
  2. Sembra che tu non stia sfruttando pienamente i segnali e gli slot. È necessario l'oggetto che crea la finestra di dialogo (o un'altra) per ascoltare i segnali della finestra di dialogo.
  3. Nel codice non si collegano i segnali agli slot.
  4. Con la mia correzione onOKButtonClicked e onCancelButtonClicked non sono necessari.
  5. Con la mia correzione non è necessario showYourself(). Basta chiamare lo exec e con gli eventi le informazioni scorreranno.

È necessario aggiungere questo codice prima di mostrare la finestra di dialogo (this assumere è in un metodo di dialogo):

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

Nell'oggetto chiamante avete

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

Grazie! Questo è illuminante. Se faccio questo, devo cancellare esplicitamente l'oggetto, o è gestito internamente? – go4sri

+0

se l'oggetto ha un genitore viene eliminato quando il genitore viene eliminato. Puoi usare 'QObject :: deleteLater()' per pianificare un'eliminazione. Quando sai per certo che un oggetto non è più usato (nessun evento relativo a questo oggetto che gira intorno) puoi usare il buon vecchio delete. – UmNyobe

+0

ottima risposta! grazie! – Victor

8

Caso 1 Fare clic sui pulsanti non chiude la finestra di dialogo.

Per questo è necessario per chiudere la finestra sul rispettivo SLOTS, in modo da utilizzare

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

Nota: Solo dopo aver fatto clic sul pulsante Ok o il pulsante Annulla in un QMessageBox normale, la funzione setResult() viene attivato e lo stato è cambiato. Non è lo stesso effetto quando si fa il contrario.

Caso 2 Il valore restituito non è corretto.

Penso che solo dopo la chiusura della finestra di dialogo, il risultato sarà disponibile nella funzione result(). Quindi immagino che sarà risolto, dopo aver apportato le modifiche specificate nel Caso 1.

Se persiste, utilizzare la propria funzione membro privata per risolverlo.

+0

Grazie. che funzioni. – go4sri

+4

Chiamando questo-> close() dopo aver impostato questo-> setResult (QDialog :: Accepted); farà sì che il risultato finisca per essere 0 anziché 1. Quindi chiama il setResult() dopo la chiusura() – ManuelH

14

Un'altra soluzione:

// 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 } 
Problemi correlati