简体   繁体   English

循环中的 QMessageBox 和 QFileDialog

[英]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.为此,我对QMessageBox进行了子类化,添加了一些自定义内容(例如使对话框更宽的间隔器),并且我正在调用QFileDialog::getExistingDirectory来获取目录。

Thing is, user can click Cancel in QFileDialog .问题是,用户可以在QFileDialog单击 Cancel 。 But I want user to be returned to QMessageBox to have another chance to set path or quit program altogether.但我希望用户返回到QMessageBox有另一个机会设置路径或完全退出程序。 To achieve that I wrote method loop() :为了实现这一点,我编写了方法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() :然后,我有一个方法getPath()

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

which I call in main.cpp :我在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() .我特别询问这个while里面驻留方法exec()

IMO disadvantages of your decision:您决定的 IMO 缺点:

  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.将奇怪的循环放在某个 GUI 方法中并在其中调用标准的exec()方法,此时该方法可以很容易地以标准方式调用。
  2. Hide exec() call from "user" (another programmer)隐藏来自“用户”(另一个程序员)的exec()调用
  3. Dual, or even triple, purpose of the one getPath() method:一个getPath()方法的双重甚至三重目的:
    • 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?):我建议继承QDialog (为什么是消息框?):

In Degister I put on form standard Push Button setPathButton and Dialog Button Box buttonBox .在 Degister 中,我采用了标准的 Push Button setPathButton和 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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