使用 QSortFilterItemProxy 保持结构

Keep structure using QSortFilterItemProxy

所以我使用了一个稍微自定义的 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 中获取父项,但它似乎总是空的。

这似乎是一件容易做的事情,或者只是我错过的一个设置,但我们将不胜感激任何帮助!

谢谢!

你似乎想要的是 filterAcceptsRow 应该 return 如果行本身通过测试 它的任何后代通过测试.

基于此,您可能想尝试一些相当基本的东西,例如...

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;
    }
};

有点'brute force',因为同一行最终可能会被多次测试,但如果您的模型不是太大,那应该不是问题。更好的算法会在用户定义的模型角色中使用额外数据来缓存调用 sort_filter_proxy::test.

生成的结果