9

我有一个QDirModel其当前目录已设置。然后我有一个QListView应该显示该目录中的文件。这工作正常。

现在我想限制显示的文件,所以它只显示png文件(文件名以 .png 结尾)。问题是使用 aQSortFilterProxyModel并设置过滤器正则表达式也会尝试匹配文件的每个父级。根据文档:

对于分层模型,过滤器递归地应用于所有子级。如果父项与过滤器不匹配,则不会显示其子项。

那么,我如何QSortFilterProxyModel才能只过滤目录中的文件,而不是它所在的目录?

4

5 回答 5

10

对于像我这样对以下行为感兴趣的人:如果一个孩子匹配过滤器,那么它的祖先不应该被隐藏:

bool MySortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const
{
    // custom behaviour :
    if(filterRegExp().isEmpty()==false)
    {
        // get source-model index for current row
        QModelIndex source_index = sourceModel()->index(source_row, this->filterKeyColumn(), source_parent) ;
        if(source_index.isValid())
        {
            // if any of children matches the filter, then current index matches the filter as well
            int i, nb = sourceModel()->rowCount(source_index) ;
            for(i=0; i<nb; ++i)
            {
                if(filterAcceptsRow(i, source_index))
                {
                    return true ;
                }
            }
            // check current index itself :
            QString key = sourceModel()->data(source_index, filterRole()).toString();
            return key.contains(filterRegExp()) ;
        }
    }
    // parent call for initial behaviour
    return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) ;
}
于 2012-06-06T09:45:04.107 回答
7

我们在我工作的地方遇到了类似的事情,最终制作了我们自己的代理模型来进行过滤。但是,通过查看您想要的文档(这似乎是一种更常见的情况),我遇到了两种可能性。

  1. 您也许可以在 QDirModel 上设置名称过滤器并以这种方式过滤事物。我不知道这是否会像你想要的那样工作,或者名称过滤器是否也适用于目录。这些文档有点稀疏。
  2. 子类化 QSortFilterProxyModel 并覆盖该filterAcceptsRow函数。从文档中:

自定义过滤行为可以通过重新实现 filterAcceptsRow() 和 filterAcceptsColumn() 函数来实现。

然后您大概可以使用模型索引来检查索引项是目录(自动接受)还是文件(过滤文件名)。

于 2008-10-31T15:41:08.250 回答
6

从 Qt 5.10 开始,QSortFilterProxyModel可以选择递归过滤。换句话说,如果一个孩子匹配过滤器,它的父母也将是可见的。

查看QSortFilterProxyModel::recursiveFilteringEnabled

于 2019-03-07T18:41:45.573 回答
2

导出 qsortfilterproxymodel 然后...

bool YourQSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
{
    if (source_parent == qobject_cast<QStandardItemModel*>(sourceModel())->invisibleRootItem()->index())
    {
        // always accept children of rootitem, since we want to filter their children 
        return true;
    }

    return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
于 2010-11-05T12:56:33.317 回答
-1

只需使用KItemModels KDE API中的KRecursiveFilterProxyModel模型

于 2015-09-02T19:11:50.370 回答