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

here で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 に答える