2

我现在正在使用QFileDialog::getOpenFileName。但是,正如本文所建议的,当主应用程序在对话框打开时关闭时,这会崩溃。您可以在此处查看如何重现崩溃的示例:

int main(int argc, char **argv) {
  QApplication application{argc, argv};

  QMainWindow *main_window = new QMainWindow();
  main_window->show();

  QPushButton *button = new QPushButton("Press me");
  main_window->setCentralWidget(button);

  QObject::connect(button, &QPushButton::clicked, [main_window]() {
    QTimer::singleShot(2000, [main_window]() { delete main_window; });

    QFileDialog::getOpenFileName(main_window, "Close me fast or I will crash!");
  });

  application.exec();
  return 0;
}

我可以改用QFileDialog普通的构造函数,如此所述。但是,然后我似乎没有得到本机 Windows 文件打开对话框。

有没有办法获得一个非崩溃程序并通过 Qt 使用本机 Windows 文件打开对话框?

4

2 回答 2

2

如果您关闭main_window而不是删除它,则不会发生任何崩溃。

顺便说一句,您可以检查是否有任何QFileDialog打开以避免错误的应用程序退出。

在下一个示例中,我将关闭对话框,但您可以实现另一个解决方案:

#include <QTimer>
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QFileDialog>
#include <QDebug>

int main(int argc, char **argv) {
  QApplication application{argc, argv};

  QMainWindow *main_window = new QMainWindow();
  main_window->show();

  QPushButton *button = new QPushButton("Press me");
  main_window->setCentralWidget(button);

  QObject::connect(button, &QPushButton::clicked, [main_window]() {
    QTimer::singleShot(2000, [main_window]() {

        QObjectList list = main_window->children();

        while (!list.isEmpty())
        {
            QObject *object= list.takeFirst();

            if (qobject_cast<QFileDialog*>(object))
            {
                qDebug() << object->objectName();
                QFileDialog* fileDialog = qobject_cast<QFileDialog*>(object);
                fileDialog->close();
            }
        }

        main_window->close();
    });

    QFileDialog::getOpenFileName(main_window, "Close me fast or I will crash!");
  });

  application.exec();
  return 0;
}
于 2016-07-12T12:47:31.150 回答
0

您的应用程序设计已损坏。应用程序的关闭通常发生在主线程中最外层的事件循环存在时。当文件对话框处于活动状态时,这不会发生 - 根据定义,它的事件循环正在运行。因此,您正在做一些您不应该做的事情,而文件对话框只是替罪羊,或者是煤矿中的金丝雀,表明其他地方已经破碎。

于 2016-07-11T17:58:48.310 回答