web-dev-qa-db-fra.com

QDialog exec () et obtention de la valeur du résultat

J'ai sous-classé QDialog pour implémenter des fonctionnalités similaires à QMessageBox (j'en avais besoin pour permettre la personnalisation). Il a un message texte et des boutons OK, Annuler. Je montre la boîte de dialogue en utilisant exec() pour la bloquer. Maintenant, comment puis-je retourner les valeurs true/false lorsque l'utilisateur clique sur OK/Annuler?

J'ai essayé de connecter les boutons à setResult() puis, renvoyer la valeur du résultat lorsque vous cliquez dessus, mais

  1. Cliquer sur les boutons ne ferme pas la boîte de dialogue
  2. la valeur de retour est incorrecte. Voici le code que j'ai écrit. Je pense que je me trompe dans la partie exec/result - mais je ne sais pas comment y remédier.
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'utilisateur instanciera la classe et appellera showYourself() qui devrait renvoyer la valeur et fermera (et supprimera) la boîte de dialogue.

J'ai publié un code partiel. Faites-moi savoir si vous en avez besoin et je publierai la version complète.

22
go4sri

Quelques points :

  1. Plutôt que d'utiliser setResult() vous-même, utilisez QDialog :: accept () et QDialog :: rejet () .
  2. Il semble que vous ne profitiez pas pleinement des signaux et des créneaux horaires. Vous avez besoin de l'objet qui crée la boîte de dialogue (ou une autre) pour écouter les signaux de la boîte de dialogue.
  3. Dans votre code, vous ne connectez pas non plus les signaux aux emplacements.
  4. Avec mon correctif onOKButtonClicked et onCancelButtonClicked ne sont pas nécessaires.
  5. Avec ma correction, vous n'avez pas besoin de showYourself(). Appelez simplement exec et les informations sur les événements circuleront.

Vous devez ajouter ce code avant d'afficher la boîte de dialogue (this supposez qu'il se trouve dans une méthode de dialogue):

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

Dans l'objet appelant, vous avez

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
}
26
UmNyobe

Une autre solution:

    // 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 }
17
Jens A. Koch

Cas 1 Cliquer sur les boutons ne ferme pas la boîte de dialogue.

Pour cela, vous devez fermer la boîte de dialogue sur les SLOTS respectifs, donc utilisez

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

Remarque: Ce n'est qu'après avoir cliqué sur le bouton Ok ou Annuler dans un QMessageBox standard, que la fonction setResult () est déclenchée et que l'état est modifié. Ce n'est pas le même effet lorsqu'il est fait vice versa.

Cas 2 La valeur de retour est incorrecte.

Je pense qu'après la fermeture de votre boîte de dialogue, le résultat sera disponible dans la fonction result(). Je suppose donc que cela sera résolu, après avoir apporté les modifications spécifiées dans le cas 1.

S'il persiste, utilisez votre propre fonction de membre privé pour le résoudre.

9
ScarCode