交互目标
跳转到“交互目标”点击按钮后选择一个文件夹,标签显示路径,下拉框显示该目录的直接子项。取消选择时保持原有界面。这里使用 Qt Widgets 的 QFileDialog 和 QDir,不涉及递归遍历。
槽函数
跳转到“槽函数”假设 UI 中已有 toolButton、label、comboBox,且按钮已连接到该槽函数。
#include <QDir>#include <QFileDialog>#include <QFileInfo>#include <QMessageBox>
void MainWindow::on_toolButton_clicked(){ const QString selected = QFileDialog::getExistingDirectory( this, tr("选择文件夹"), QDir::homePath());
// 必须先处理取消,再清空旧列表或更新标签。 if (selected.isEmpty()) return;
const QDir directory(selected); if (!directory.exists() || !QFileInfo(selected).isReadable()) { QMessageBox::warning(this, tr("无法读取"), tr("请检查目录与访问权限。")); return; }
const QFileInfoList entries = directory.entryInfoList( QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst | QDir::Name);
ui->comboBox->clear(); ui->label->setText(QDir::toNativeSeparators(selected)); for (const QFileInfo &entry : entries) { ui->comboBox->addItem(entry.fileName(), entry.absoluteFilePath()); }}getExistingDirectory() 用于选择目录;entryInfoList() 根据过滤器与排序方式返回目录项。这里过滤 . 和 ..,没有开启隐藏文件显示。QFileDialog、QDir
显示名与路径分开保存
跳转到“显示名与路径分开保存”下拉框文字适合显示短文件名,真正操作文件时读取 currentData().toString() 中的完整路径。不要只拼接当前工作目录和显示名,因为应用的工作目录可能变化,不同目录也可能存在同名文件。
列表为空可能表示目录本来为空、过滤后没有项目,或读取期间发生了权限/目录变化。正式工具还应显示状态提示,并在打开选中项时再次处理文件已经被删除等情况。
单文件、多文件与保存路径
跳转到“单文件、多文件与保存路径”不同目的使用不同接口,不能只修改对话框标题来改变选择语义。
| 目的 | 常用接口 | 返回值 |
|---|---|---|
| 打开一个已有文件 | getOpenFileName | QString |
| 打开多个已有文件 | getOpenFileNames | QStringList |
| 选择已有目录 | getExistingDirectory | QString |
| 选择保存位置 | getSaveFileName | QString |
例如打开一张图片:
const QString fileName = QFileDialog::getOpenFileName( this, tr("选择图片"), QDir::homePath(), tr("图片 (*.png *.jpg *.jpeg);;所有文件 (*)"));if (!fileName.isEmpty()) ui->lineEdit->setText(QDir::toNativeSeparators(fileName));文件名过滤器只控制候选显示,实际读取仍要检查格式是否可解码。原“选择文件夹”片段返回 fileFolder 却显示未定义的 fileName,变量应保持一致。
自定义显示与选择模式
跳转到“自定义显示与选择模式”需要调整视图时可以使用实例化的 QFileDialog:
QFileDialog dialog(this, tr("选择文件"), QDir::homePath());dialog.setOption(QFileDialog::DontUseNativeDialog, true);dialog.setFileMode(QFileDialog::ExistingFiles);dialog.setViewMode(QFileDialog::Detail);if (dialog.exec() == QDialog::Accepted) { const QStringList selectedFiles = dialog.selectedFiles(); // 在数据模型中保存完整列表,再逐项处理。}AnyFile 可表示尚不存在的文件,常用于保存场景,不等于“文件和目录随意混合多选”。原自定义代码查找内部名为 buttonBox/listView 的部件并绕过 QFileDialog 的 accept 校验,这依赖内部实现,换样式或版本可能失效。
若业务确实需要文件和目录混选,可提供“添加文件”和“添加目录”两个清晰入口,或基于文件系统模型实现自己的选择列表并校验每项类型。不要把以分号拼接的显示字符串作为唯一存储,因为文件名本身可能含分号。选择模式与选项
修正点
跳转到“修正点”原截图在取消目录对话框后仍构造 QDir(path)。空路径可能回落到当前目录,容易误显示非预期内容。本版先检查空字符串,再更新界面。示例针对常见小目录;很大目录的枚举应移出 GUI 主线程,以免界面停顿。