Скрыть элементы QFileSystemModel/QTreeView через индексы, используя определенное правило

Я показываю содержимое папки в своей программе Qt, используя QTreeView + QFileSystemModel.

Теперь я хочу скрыть определенные элементы этого представления. Правило отображения не основано на именах файлов, поэтому я не могу использовать setNameFilters(). У меня есть простой список QModelIndex, содержащий все элементы, которые я хочу скрыть. Есть ли способ отфильтровать представление, используя только этот список?

В своем исследовании я наткнулся на класс QSortFilterProxyModel, но не мог понять, как его использовать для достижения того, чего я хочу. Любая помощь будет оценена по достоинству.


person Pericles Carvalho    schedule 07.04.2019    source источник


Ответы (1)


Подкласс QSortFilterProxyModel и переопределение метода filterAcceptsRow для установки логики фильтра.

Например, чтобы отфильтровать права текущего пользователя на запись :

class PermissionsFilterProxy: public QSortFilterProxyModel
{
public:
    PermissionsFilterProxy(QObject* parent=nullptr): QSortFilterProxyModel(parent)
    {}

    bool filterAcceptsRow(int sourceRow,
            const QModelIndex &sourceParent) const
    {
        QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
        QFileDevice::Permissions permissions = static_cast<QFileDevice::Permissions>(index.data(QFileSystemModel::FilePermissions).toInt());
        return permissions.testFlag(QFileDevice::WriteUser); // Ok if user can write
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QFileSystemModel* model = new QFileSystemModel();
    model->setRootPath(".");

    QTreeView* view = new QTreeView();
    PermissionsFilterProxy* proxy = new PermissionsFilterProxy();
    proxy->setSourceModel(model);
    view->setModel(proxy);
    view->show();
    return app.exec();
}
person Dimitry Ernot    schedule 07.04.2019
comment
Большое спасибо! Это работает, но фильтр не обновляется каждый раз, когда я меняю условия. В моем случае элементы, которые должны быть скрыты, хранятся в списке. Знаете ли вы, как я могу автоматически обновлять фильтры при обновлении списка? - person Pericles Carvalho; 08.04.2019
comment
Забудь об этом, я только что понял. Мне просто нужно было выдать sourceModel()->dataChanged() при изменении условий. Еще раз большое спасибо! - person Pericles Carvalho; 08.04.2019
comment
Вы также можете вызвать QSortFilterProxyModel::invalidateFilter(), если хотите изменить параметры фильтра. - person Dimitry Ernot; 08.04.2019