2012-09-18 29 views
14

He subclase QDialog para implementar una funcionalidad similar a QMessageBox (necesitaba esto para permitir la personalización). Tiene un mensaje de texto y botones Aceptar, Cancelar. Estoy mostrando el cuadro de diálogo usando exec() para bloquearlo. Ahora, ¿cómo devuelvo los valores de verdadero/falso cuando el usuario hace clic en Aceptar/Cancelar?QDialog exec() y obteniendo el valor de resultado

traté de conectar los botones para setResult() y luego, devuelva el valor del resultado cuando se hace clic, pero 1. Al hacer clic en los botones no se cierra el cuadro de diálogo 2. El valor devuelto es incorrecto. A continuación se encuentra el código que he escrito. Creo que estoy equivocado en la parte de ejecución/resultado, pero no estoy seguro de cómo solucionarlo.

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

    }; 

El usuario tendrá una instancia de la clase y llamar showYourself() que se espera para devolver el valor y también cerca (y eliminar) el diálogo.

He publicado el código parcial. Avíseme si necesita más y publicaré la versión completa.

Respuesta

15

Algunos puntos:

  1. En lugar de utilizar setResult() mismo, el uso QDialog::accept() y QDialog::reject().
  2. Parece que no está aprovechando al máximo las señales y las ranuras. Necesita el objeto que crea el diálogo (u otro) para escuchar las señales del diálogo.
  3. En su código tampoco está conectando señales a las ranuras.
  4. Con mi corrección onOKButtonClicked y onCancelButtonClicked son innecesarios.
  5. Con mi solución no necesita showYourself(). Simplemente llame al exec y con los eventos fluirá la información.

Es necesario añadir este código antes de mostrar el cuadro de diálogo (this asuma que está en un método de diálogo):

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

En el objeto de la persona que llama tiene

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

¡Gracias! Eso es iluminador. Si hago esto, ¿necesito eliminar explícitamente el objeto o me ocupo de ello internamente? – go4sri

+0

si el objeto tiene un padre, se elimina cuando se elimina el padre. Puede usar 'QObject :: deleteLater()' para programar una eliminación. Cuando sepa con certeza que ya no se usa un objeto (no hay ningún evento relacionado con este objeto que esté flotando), puede usar la buena eliminación anterior. – UmNyobe

+0

muy buena respuesta! ¡gracias! – Victor

8

Caso 1 Al hacer clic en los botones no se cierra el cuadro de diálogo.

Para ello se tiene que cerrar el diálogo sobre respectiva SLOTS, a fin de utilizar

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

Nota: Sólo después de haber hecho clic en el botón OK o el botón Cancelar en un QMessageBox estándar, la función setResult() se dispara y el estado es cambiado. No es el mismo efecto cuando se hace al revés.

Caso 2 El valor de retorno es incorrecto.

Creo que solo después de que se cierre el cuadro de diálogo, tendrá el resultado disponible en la función result(). Así que supongo que se resolverá, después de haber realizado los cambios especificados en el Caso 1.

Si aún persiste, use su propia función de miembro privado para resolverlo.

+0

Gracias. eso funciona. – go4sri

+4

Llamar a esto-> cerrar() después de establecer esto-> setResult (QDialog :: Accepted); hará que el resultado termine siendo 0 en lugar de 1. Entonces llame al setResult() después del cierre() – ManuelH

14

Otra solución:

// 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 } 
Cuestiones relacionadas