QFileDialog: возможно ли фильтровать только исполняемые файлы (под Linux)? - PullRequest
0 голосов
/ 07 мая 2018

Я хочу использовать QFileDialog, чтобы пользователь выбирал исполняемый файл. Диалог должен показывать только актуальные исполняемые файлы, кроме каталогов.

Моя версия для 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);

Однако этот код приводит к отображению всех файлов.

Я экспериментировал с добавлением некоторых других фильтров, но пока ничего не получалось. В StackOverflow уже есть два вопроса, которые по сути совпадают с моими, оба без реального ответа:

Фильтрация исполняемых файлов в QFileDialog в Linux

показывать только каталоги и исполняемые файлы в Ubuntu, использующие QFileDialog

Кто-нибудь знает, как это можно сделать? Или QFileDialog просто не в состоянии это сделать? Можно ли это сделать вообще или распознавание исполняемых файлов не так просто в целом?

(Примечание: я работаю с Qt 4.8.5, так как использую сторонний код, который несовместим с Qt 5, если это имеет значение.)

(Примечание: не помечал это как C ++, так как это также относится к Python.)

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Использовать модель прокси для диалога файлов.

В моем случае код выглядит следующим образом:

#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)

Полные источники

0 голосов
/ 31 августа 2018

если вы используете собственные диалоговые окна файлов, некоторые настройки не действуют.

Это должно работать:

   QFileDialog dlg(this, tr("Select executable"));
   dlg.setOption(QFileDialog::DontUseNativeDialog, true);
   dlg.setFilter(QDir::Executable | QDir::Files);

Обратите внимание, что это файлер только исполняемые файлы. Для показа папок одновременно не существует известного решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...