Regular Expression Filter for QFileDialog
Asked Answered
B

2

0

I would like to display a file open dialog that filters on a particular pattern, for example *.000 to *.999.

QFileDialog::getOpenFileNames allows you to specify discrete filters, such as *.000, *.001, etc. I would like to set a regular expression as a filter, in this case ^.*\.\d\d\d$, i.e. any file name that has a three digit extension.

Bowers answered 2/2, 2017 at 6:48 Comment(0)
B
1

ariwez pointed me into the right direction. The main thing to watch out for is to call dialog.setOption(QFileDialog::DontUseNativeDialog) before dialog.setProxyModel.

The proxy model is:

class FileFilterProxyModel : public QSortFilterProxyModel
{
protected:
    virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
    {
        QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
        QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel());

        // I don't want to apply the filter on directories.
        if (fileModel == nullptr || fileModel->isDir(index0))
            return true;

        auto fn = fileModel->fileName(index0);

        QRegExp rx(".*\\.\\d\\d\\d");
        return rx.exactMatch(fn);
    }
};

The file dialog is created as follows:

QFileDialog dialog;

// Call setOption before setProxyModel.
dialog.setOption(QFileDialog::DontUseNativeDialog);
dialog.setProxyModel(new FileFilterProxyModel);
dialog.exec();
Bowers answered 7/2, 2017 at 6:41 Comment(0)
J
1

It can be done by adding proxy model to QFileDialog. It is explained here: Filtering in QFileDialog

Jocko answered 2/2, 2017 at 7:56 Comment(3)
According to the Qt documentation, this should work. I have followed the instructions in the link above, however, filterAcceptsRow of the sub class is never called.Bowers
I should add that I am using Qt 5.4.1, Win 10 and VS 2013.Bowers
Well, with Qt5 and VS dialog.setProxyModel(&filter) is not working - and dialog.proxyModel() remains null so no filtering is being done.Jocko
B
1

ariwez pointed me into the right direction. The main thing to watch out for is to call dialog.setOption(QFileDialog::DontUseNativeDialog) before dialog.setProxyModel.

The proxy model is:

class FileFilterProxyModel : public QSortFilterProxyModel
{
protected:
    virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
    {
        QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
        QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel());

        // I don't want to apply the filter on directories.
        if (fileModel == nullptr || fileModel->isDir(index0))
            return true;

        auto fn = fileModel->fileName(index0);

        QRegExp rx(".*\\.\\d\\d\\d");
        return rx.exactMatch(fn);
    }
};

The file dialog is created as follows:

QFileDialog dialog;

// Call setOption before setProxyModel.
dialog.setOption(QFileDialog::DontUseNativeDialog);
dialog.setProxyModel(new FileFilterProxyModel);
dialog.exec();
Bowers answered 7/2, 2017 at 6:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.