5

I'm trying to create a QFileDialog on Ubuntu that will allow the user to select an executable file, with the intent being that the file is a desktop application (i.e. analogous to the .exe subset of executable files on Windows).

On Windows, this is achieved using setNameFilter to look for "(*.exe)" files, but since Ubuntu obviously doesn't use extensions for executables, you need to use the QDir::Filters method.

You'd think that the following would do the trick

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

but it actually has the effect of filtering out 99% of file system entries, including almost every directory, making it impossible to navigate.

It seems like the QFileDialog::setFilter function applies all the filters and permissions to every file and directory it looks at, with the problem being that directories and executable programs are (pretty much) mutually exclusive, and I can't figure out on Ubuntu what the right combination is to achieve "Any directory, or only those files which can be executed as a program".

I've additionally tried most permutations of AllDirs, Dirs, Executable, AllEntries, etc. so I don't think it's as simple as one missing property.

Some other permutations I've tried:

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

With the results:

  1. everything is filtered out
  2. everything is filtered out
  3. nothing is filtered out

There's a related question regarding PyQt, which was never answered, and also I'm not sure the OP of that question wanted directories to be visible.

Community
  • 1
  • 1
Nicolas Holthaus
  • 7,763
  • 4
  • 42
  • 97

2 Answers2

2

Use proxy model for file dialog

My code is the following:

#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 ) {
    ...
}

This shows executables and folders, tested on both Linux and Windows (Qt 4.8.6)

Full sources

See also QFileDialog: is it possible to filter only executables (under Linux)?

-2

I use QDir. Works with linux fine, here's an example:

QDir dir = QDir("Path");
QStringList data = dir.entryList(QDir::Executeable | QDir::Files | QDir::NoDotAndDotDot);
// This line should return a QStringList with names of files in 
//your specified directory. It will get every executeable that is a file

If it doesn't get you what you want just remove the QDir::Executeable

I have written a backup program with QDir based search algorithm (recursion) and never had a problem in linux or windows. Maybe it does work for you.

Just put in the path that you wanna look through, and include , and ;)

Have a nice day

Vancold.at
  • 138
  • 7
  • I'm not trying to get the `entryList` from a directory, I'm trying to filter a `QFileDialog`. It's not the same problem. There is no specified directory, because it needs to come from user input in the dialog, but the user can't navigate to said directory if all the directories are being filtered out of the dialog. And if I set the permissions like I showed in the question to the point where I get the directories back, the user can select any file, even non-programs, which in my case are invalid inputs. – Nicolas Holthaus Apr 17 '16 at 15:48
  • Hmm i might be able to come up with something. – Vancold.at Apr 18 '16 at 12:42