[C++]QFileDialogで最後に開いたフォルダ。

 QFileDialogは最後に開いたフォルダを保存しておき、次にダイアログを開いた時は最初からそのフォルダを開くようになっている1。この“最後に開いたフォルダ”は全てのQFileDialogのインスタンスで共有されているので、その情報はstaticメンバないしグローバル変数として保管されているはずだ。この“最後のフォルダ”を取得する方法はないのだろうか。例えばこのフォルダ情報を.iniに書き出しておいて、アプリケーションの次回起動時に“最後のフォルダ”を復元できれば地味にありがたい。

 結論から言えば、スマートな方法はない。少なくともQFileDialog::lastDir()のような便利な静的メンバ関数などは存在しない。
 QFileDialogの実装を見ていると、確かにこの情報を格納している"lastVisitedDir"というグローバル変数が存在するのだが、これは完全に.cppファイルの中に隠蔽されており、QFileDialogのpublicメンバからも取り出すことが出来ないようだった。

 代替案はある。QFileDialogを使うたびに、取得したファイルの情報からフォルダを取り出して、自ら用意した変数に格納しておけばよい。例えば次のような関数を用意しておき、QFileDialog::getOpenFileNameの代わりに使う。そうすることで、gLastDirがGetOpenFileNameを呼ぶたびに更新される。

QUrl gLastDir;

QString GetOpenFileName(QWidget *parent = nullptr,
                               const QString &caption = QString(),
                               const QString &filter = QString(),
                               QString *selectedFilter = nullptr,
                               QFileDialog::Options options = QFileDialog::Options())
{
    const QStringList supportedSchemes = QStringList(QStringLiteral("file"));
    QFileDialog dialog(parent, caption, gLastDir.toLocalFile(), filter);
    dialog.setSupportedSchemes(supportedSchemes);
    dialog.setOptions(options);
    if (selectedFilter && !selectedFilter->isEmpty())
        dialog.selectNameFilter(*selectedFilter);
    if (dialog.exec() == QDialog::Accepted)
    {
        if (selectedFilter)
            *selectedFilter = dialog.selectedNameFilter();
        QUrl path = dialog.selectedUrls().value(0);
        *gLastDir = dialog.directoryUrl();
        return path.toLocalFile();
    }
    return QUrl().toLocalFile();
}

 下策ではあるものの、一応動く。私の意図した通りの挙動ではあるし、開くダイアログによって“最後のフォルダ”情報の格納場所を分けたい場合などはむしろこれが有効だろう。とはいえ、たった一つQFileDialog::lastDir関数を用意してくれれば解決したのにと思わなくはない。


  1. 開くフォルダを明示的に与えなかった場合。