c++ - 使用 QFileDialog 在 Ubuntu 上仅显示目录和可执行文件

标签 c++ qt ubuntu file-permissions qfiledialog

我正在尝试在 Ubuntu 上创建一个 QFileDialog,它允许用户选择一个可执行文件,目的是该文件是一个桌面应用程序(即类似于 .exe Windows 上可执行文件的子集)。

在 Windows 上,这是通过使用 setNameFilter 来查找 "(*.exe)" 文件来实现的,但是由于 Ubuntu 显然不使用可执行文件的扩展名,所以你需要使用 QDir::Filters 方法。

您会认为以下内容可以解决问题

QFileDialog dialog;
dialog.setFilter(QDir::AllDirs | QDir::Executable);
// ...
dialog.exec();

但它实际上具有过滤掉 99% 的文件系统条目的效果,包括几乎每个目录,使其无法导航。

似乎 QFileDialog::setFilter 函数将所有过滤器和权限应用于它查看的每个文件 目录,问题是目录和可执行程序是(几乎)互斥的,我无法在 Ubuntu 上弄清楚什么是正确的组合来实现“任何目录,或仅那些可以作为程序执行的文件”。

我还尝试了 AllDirsDirsExecutableAllEntries 等的大多数排列,所以我认为这不像缺少一个属性那么简单。

我尝试过的一些其他排列:

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

结果:

  1. 一切都被过滤掉
  2. 一切都被过滤掉
  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) 上测试的可执行文件和文件夹

Full sources

另见 QFileDialog: is it possible to filter only executables (under Linux)?

关于c++ - 使用 QFileDialog 在 Ubuntu 上仅显示目录和可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36676836/

相关文章:

qt - 如何删除有关在 Qt 中使用 scanf 的警告?

Qt 创建可执行文件

ubuntu - 将 p4 diff 更改为 diff 在 ubuntu 中不起作用

ubuntu - File_put_contents(./composer.lock) : Failed to open stream: Permission denied

java - 适用于 Ubuntu 12.10 的 Android 模拟器(Arm 安装)?

c++ - 这个简单的程序会有多少缓存未命中?

c++ - 我可以创建匹配枚举类型的类模板的部分模板特化吗?

c++ - 如何在 C++ 中保存 .txt 文件?

html - 如果我将 html 与 QTextEdit 一起使用,打字会很乱

C++ 异常未在线程中处理