c++ - C++ 选择文件夹,包含文件
问题描述
我目前正在为 Windows 开发一个 qt 应用程序。用户需要能够选择一个目录来加载所有文件。我有一个与此相关的问题。这似乎很愚蠢,但我一直得到相同的反馈。最终用户对文件对话框感到困惑,因为他们导航到该文件夹,但它不显示任何文件。即使他们正在选择一个文件夹,这也会让他们感到困惑,因为他们看不到目录中的文件。
所以我决定深入研究它并做一些研究。从我发现的情况来看,似乎基本上有两种选择。IFileOpenDialog
with ,这FOS_PICKFOLDERS
是我目前通过 qt's 使用的QFileDialog
。或者SHBrowseForFolder
,它确实有效,但非常有限。
我错过了任何选择吗?似乎IFileOpenDialog
在不允许用户选择文件的情况下显示文件是理想的。有没有办法做到这一点?我发现很多旧信息都说这是不可能的,但没有任何确定的信息是最近的。
解决方案
主要问题是,如文档中所述,Windows 的本机文件对话框不支持仅在选择目录时同时显示文件和目录(也请查看其他相关答案)。对于QFileDialog::FileMode::Directory
:
目录的名称。显示文件和目录。但是,本机 Windows 文件对话框不支持在目录选择器中显示文件。
一种解决方法是使用非本机文件对话框进行这种选择,但就个人而言,如果它必须与其他本机文件对话框一起使用,它看起来很糟糕。
这里快速比较了两种选择目录的方法,使用QFileDialog::getExistingDirectory
、手动创建实例QFileDialog
和使用 native IFileDialog
:
#include <qapplication.h>
#include <qfiledialog.h>
#include <qdebug.h>
#include <Windows.h>
#include <shobjidl.h>
void using_IFileDialog()
{
IFileOpenDialog* pFileOpen;
HRESULT hr;
// Create the FileOpenDialog object.
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
IID_IFileOpenDialog, reinterpret_cast<void**>(&pFileOpen));
if (SUCCEEDED(hr)) {
// Show the Open dialog box.
pFileOpen->SetOptions(FOS_PICKFOLDERS | FOS_PATHMUSTEXIST);
hr = pFileOpen->Show(NULL);
// Get the file name from the dialog box.
if (SUCCEEDED(hr)) {
IShellItem* pItem;
hr = pFileOpen->GetResult(&pItem);
if (SUCCEEDED(hr)) {
PWSTR pszFilePath;
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
// Display the file name to the user.
if (SUCCEEDED(hr)) {
MessageBox(NULL, pszFilePath, L"File Path", MB_OK);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pFileOpen->Release();
}
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
const auto dir_1 = QFileDialog::getExistingDirectory(nullptr, "getExistingDirectory (dirs only)");
qDebug() << dir_1;
QFileDialog dlg(nullptr, "QFileDialog::DontUseNativeDialog");
dlg.setFileMode(QFileDialog::Directory);
dlg.setOption(QFileDialog::DontUseNativeDialog);
if (dlg.exec() == QFileDialog::Accepted) {
const auto dir_2 = dlg.directory().absolutePath();
qDebug() << dir_2;
}
using_IFileDialog();
return 0;
}
推荐阅读
- css - 如何在引导多个项目轮播列与上一个和下一个按钮之间放置间隙
- reactjs - 我可以为酶浅渲染中的变量指定一个值吗?
- r - R 不允许我将代码编织成 word 格式
- java - 问题创建 NotificationCompat 任何打开的应用程序
- javascript - 有没有其他优雅的方式从 JSON 中获取数据并将其呈现给 DOM?
- typescript - 结合联合类型对象构建
- python - 如何将列表中的字符串与列表理解结合起来?
- python - Kivy:按下按钮时更新TextInput
- react-native - Expo-React-native-map:从用户当前位置的 5 公里半径范围内查找最近的餐馆
- java - MySQL /Java 帮助 - 通过 eclipse 更新方法