QFileDialog:是否可以只过滤可执行文件(在 Linux 下)?
QFileDialog: is it possible to filter only executables (under Linux)?
我想使用 QFileDialog 让用户 select 成为可执行文件。该对话框应仅显示实际的可执行文件,目录除外。
我的 Windows 版本工作正常,只需检查扩展名是否为 exe。然而,在Linux,我并没有如愿以偿
在 C++ 中,我的尝试是这样的:
QString target_dir = ...
QFileDialog file_dialog;
file_dialog.setFilter(QDir::Executable | QDir::Files);
QString file = file_dialog.getOpenFileName(this, tr("Open Exectuable"), target_dir);
但是,此代码会导致显示 所有 个文件。
我尝试添加一些其他过滤器,但到目前为止没有任何效果。 Whosebug 上已经有两个问题与我的基本相同,都没有实际答案:
Filtering executable files in QFileDialog on Linux
show only directories and executables on Ubuntu using QFileDialog
有人知道怎么做吗?还是 QFileDialog 根本做不到?完全可以完成还是识别可执行文件通常不是那么简单?
(注意:我使用 Qt 4.8.5,因为我使用与 Qt 5 不兼容的第三方代码,如果这很重要的话。)
(注意:没有将其标记为 C++,因为它也与 Python 相关。)
如果您使用本机文件对话框,某些设置将无效。
这应该有效:
QFileDialog dlg(this, tr("Select executable"));
dlg.setOption(QFileDialog::DontUseNativeDialog, true);
dlg.setFilter(QDir::Executable | QDir::Files);
请注意,这将 仅 可执行文件。要同时显示文件夹,没有已知的解决方案。
为文件对话框使用代理模型。
在我的例子中,代码如下:
#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 让用户 select 成为可执行文件。该对话框应仅显示实际的可执行文件,目录除外。
我的 Windows 版本工作正常,只需检查扩展名是否为 exe。然而,在Linux,我并没有如愿以偿
在 C++ 中,我的尝试是这样的:
QString target_dir = ...
QFileDialog file_dialog;
file_dialog.setFilter(QDir::Executable | QDir::Files);
QString file = file_dialog.getOpenFileName(this, tr("Open Exectuable"), target_dir);
但是,此代码会导致显示 所有 个文件。
我尝试添加一些其他过滤器,但到目前为止没有任何效果。 Whosebug 上已经有两个问题与我的基本相同,都没有实际答案:
Filtering executable files in QFileDialog on Linux
show only directories and executables on Ubuntu using QFileDialog
有人知道怎么做吗?还是 QFileDialog 根本做不到?完全可以完成还是识别可执行文件通常不是那么简单?
(注意:我使用 Qt 4.8.5,因为我使用与 Qt 5 不兼容的第三方代码,如果这很重要的话。)
(注意:没有将其标记为 C++,因为它也与 Python 相关。)
如果您使用本机文件对话框,某些设置将无效。
这应该有效:
QFileDialog dlg(this, tr("Select executable"));
dlg.setOption(QFileDialog::DontUseNativeDialog, true);
dlg.setFilter(QDir::Executable | QDir::Files);
请注意,这将 仅 可执行文件。要同时显示文件夹,没有已知的解决方案。
为文件对话框使用代理模型。
在我的例子中,代码如下:
#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) 上测试的可执行文件和文件夹