我正在尝试在 Ubuntu 上创建一个 QFileDialog
,它允许用户选择一个可执行文件,目的是该文件是一个桌面应用程序(即类似于 .exe Windows 上可执行文件的子集)。
在 Windows 上,这是通过使用 setNameFilter
来查找 "(*.exe)"
文件来实现的,但是由于 Ubuntu 显然不使用可执行文件的扩展名,所以你需要使用 QDir::Filters
方法。
您会认为以下内容可以解决问题
QFileDialog dialog;
dialog.setFilter(QDir::AllDirs | QDir::Executable);
// ...
dialog.exec();
但它实际上具有过滤掉 99% 的文件系统条目的效果,包括几乎每个目录,使其无法导航。
似乎 QFileDialog::setFilter
函数将所有过滤器和权限应用于它查看的每个文件 和 目录,问题是目录和可执行程序是(几乎)互斥的,我无法在 Ubuntu 上弄清楚什么是正确的组合来实现“任何目录,或仅那些可以作为程序执行的文件”。
我还尝试了 AllDirs
、Dirs
、Executable
、AllEntries
等的大多数排列,所以我认为这不像缺少一个属性那么简单。
我尝试过的一些其他排列:
dialog.setFilter(QDir::AllDirs | QDir::Executable | QDir::Files); // 1
dialog.setFilter(QDir::AllDirs | QDir::Executable | QDir::Files |
QDir::Readable); // 2
dialog.setFilter(QDir::AllDirs | QDir::Executable | QDir::Files |
QDir::Readable | QDir::Writeable); // 3
结果:
- 一切都被过滤掉
- 一切都被过滤掉
- 没有过滤掉
有 a related question关于 PyQt,从未回答过,而且我不确定该问题的 OP 是否希望目录可见。
最佳答案
对文件对话框使用代理模型
我的代码如下:
#include <QSortFilterProxyModel>
#include <QFileSystemModel>
// Custom proxy for filtering executables
class FileFilterProxyModel : public QSortFilterProxyModel
{
private:
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
bool FileFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel());
QFileInfo file( fileModel->filePath(sourceModel()->index(sourceRow, 0, sourceParent)) );
if (fileModel!=NULL && file.isExecutable())
return true;
else
return false;
}
// usage of proxy model
QFileDialog dialog( this, tr("Choose a file"));
FileFilterProxyModel* proxyModel = new FileFilterProxyModel;
dialog.setProxyModel(proxyModel);
dialog.setOption(QFileDialog::DontUseNativeDialog); // required by proxy model
if( dialog.exec() == QDialog::Accepted ) {
...
}
这显示了在 Linux 和 Windows (Qt 4.8.6) 上测试的可执行文件和文件夹
另见 QFileDialog: is it possible to filter only executables (under Linux)?
关于c++ - 使用 QFileDialog 在 Ubuntu 上仅显示目录和可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36676836/