因此,我使用了一个稍微自定义的QSortFilterProxyModel
(刚刚实现了filterAcceptsRows
),以便从QStandardItemModel
过滤元素。目前,它可以使用setFilterRegExp
进行完美过滤,但是我遇到的问题是,由于ProxyModel
仅搜索元素,因此丢失了结构。例如,假设我具有以下结构:
Root Folder 1
|----Sub Folder 1
|-----Item 1
|-----Item 2
|-----Item 3
|----Sub Folder 2
|-----Item 1
|-----Item 2
|-----Item 3
Root Folder 2
|----Sub Folder 1
|-----Item 1
|-----Item 3
|----Sub Folder 2
|-----Item 1
|-----Item 2
|-----Item 3
完成过滤后,请过滤items
名称是否包含'2'
Item 2
Item 2
Item 2
最好将其输出:
Root Folder 1
|----Sub Folder 1
|-----Item 2
|----Sub Folder 2
|-----Item 2
Root Folder 2
|----Sub Folder 2
|-----Item 2
我当时正在考虑使用原始模型,并在元素不匹配时删除它们,但这显然是错误的方法。我试过在filterAcceptsRows
中获取父项,但它似乎总是为空。
这似乎是一件容易的事,或者只是我错过的设置,但是任何帮助将不胜感激!
谢谢!
答案 0 :(得分:1)
您似乎想要的是,filterAcceptsRow
应该在行本身通过测试或的任何后代通过测试的情况下返回true。
基于此,您可能想尝试一些基本的东西,例如...
class sort_filter_proxy: public QSortFilterProxyModel {
public:
virtual bool filterAcceptsRow (int source_row, const QModelIndex &source_parent) const
{
if (!source_parent.isValid())
return true;
return test(source_parent.model()->index(source_row, 0, source_parent));
}
private:
bool test (const QModelIndex &source_index) const
{
if (!filterRegExp().isValid())
return true;
/*
* Test source_index itself.
*/
if (source_index.data(filterRole()).toString().contains(filterRegExp()))
return true;
/*
* Test the children of source_index.
*/
for (int row = 0; row < source_index.model()->rowCount(source_index); ++row)
if (test(source_index.model()->index(row, 0, source_index)))
return true;
/*
* Neither source_index nor any of its descendants passed the test.
*/
return false;
}
};
有点“蛮力”,因为同一行可能最终要被测试多次,但是如果您的模型不是太大,那应该不是问题。更好的算法是使用用户定义的模型角色中的额外数据来缓存对sort_filter_proxy::test
的调用所生成的结果。