qfiledialog - Filtering Folders?

Solution 1:

You can try setting a proxy model for your file dialog: QFileDialog::setProxyModel. In the proxy model class override the filterAcceptsRow method and return false for folders which you don't want to be shown. Below is an example of how proxy model can look like; it'c c++, let me know if there are any problems converting this code to python. This model is supposed to filter out files and show only folders:

class FileFilterProxyModel : public QSortFilterProxyModel
{
protected:
    virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
};

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

    if (fileModel!=NULL && fileModel->isDir(index0))
    {
        qDebug() << fileModel->fileName(index0);
        return true;
    }
    else
        return false;
    // uncomment to execute default implementation
    //return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

here's how I was calling it

QFileDialog dialog;
FileFilterProxyModel* proxyModel = new FileFilterProxyModel;
dialog.setProxyModel(proxyModel);
dialog.setOption(QFileDialog::DontUseNativeDialog);
dialog.exec();

Note that the proxy model is supported by non-native file dialogs only.

Solution 2:

You can try using QDir.Dirs filter.

dialog = QtGui.QFileDialog(parentWidget)

dialog.setFilter(QDir.Dirs)

Solution 3:

serge_gubenko gave you the right answer. You only had to check the folder names and return "false" for the ones which should not be displayed. For instance, to filter out any folders named "private" you'd write:

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

    if (fileModel!=NULL && fileModel->isDir(index0))
    {
        qDebug() << fileModel->fileName(index0);
        if (QString::compare(fileModel->fileName(index0), tr("private")) == 0)
            return false;

        return true;
    }
    else
        return false;
    // uncomment to execute default implementation
    //return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
}

I already tested this and it works perfectly. serge_gubenko should receive all due credit.