简体   繁体   中英

QMessageBox and QFileDialog in a loop

I have a program that needs to check at startup if a path to project is set. For that I have subclassed QMessageBox , added some custom stuff (like spacer to make dialog wider) and I am calling QFileDialog::getExistingDirectory to get directory.

Thing is, user can click Cancel in QFileDialog . But I want user to be returned to QMessageBox to have another chance to set path or quit program altogether. To achieve that I wrote method loop() :

CustomMessageBox::loop()
{
    while (true) {
        this->exec();

        if (this->clickedButton() == setPathButton) {
            path = QFileDialog::getExistingDirectory(...);
            if (!path.isEmpty()) { break; }
        } else if (this->clickedButton() == quitButton) {
            break;
        }
    }
}

Then, I have a method getPath() :

CustomMessageBox::getPath()
{
    loop();
    return path;
}

which I call in main.cpp :

CustomMessageBox box;
QString path = box.getPath();

if (!path.isEmpty()) {
    // save path, bla, bla
} else {
    exit(EXIT_FAILURE)
}

This works, but is this a good practice? I am specifically asking regarding this while inside which resides method exec() .

IMO disadvantages of your decision:

  1. Non-standard usage of dialog class. Put strange loop inside some GUI method and call standard exec() method inside it, when the method can easily be called in a standard way.
  2. Hide exec() call from "user" (another programmer)
  3. Dual, or even triple, purpose of the one getPath() method:
    • show dialog
    • flag that the dialog was accepted/rejected via empty - non-empty string
    • return directory path string

I suggest inherit QDialog (why message box?):

In Degister I put on form standard Push Button setPathButton and Dialog Button Box buttonBox . Then I removed "Ok" button from the box:

在此处输入图片说明

#include <QtWidgets/QDialog>
#include "ui_CustomDialog.h"

class CustomDialog : public QDialog
{
    Q_OBJECT

public:
    CustomDialog(QWidget *parent = nullptr);

    QString path() const { return m_path; };

private slots:
    void on_setPathButton_clicked();
    void on_buttonBox_rejected(); // You can use any pushButton instead: on_closeButton_clicked()

private:
    Ui::CustomDialogClass ui;
    QString m_path;
};

...

#include "CustomDialog.h"    
#include <QFileDialog>

CustomDialog::CustomDialog(QWidget *parent)
    : QDialog(parent)
{
    ui.setupUi(this);
}

void CustomDialog::on_setPathButton_clicked()
{
    m_path.clear();
    QString dir = QFileDialog::getExistingDirectory();

    if (!dir.isEmpty())
    {
        m_path = dir;
        done(QDialog::Accepted);
    }
}

// You can use any pushButton instead: void on_closeButton_clicked()
void CustomDialog::on_buttonBox_rejected()
{
    reject();
}

main.cpp

#include "CustomDialog.h"
#include <QtWidgets/QApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    CustomDialog box;    
    int code = box.exec();

    if (code == QDialog::Accepted)
    {
        qDebug() << box.path(); 
        // save path, bla, bla
    }
    else
    {
        exit(EXIT_FAILURE);
    }

    return a.exec();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM