使用QSortFilterItemProxy保持结构

时间:2020-04-09 15:49:15

标签: qt qstandarditemmodel qsortfilterproxymodel

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

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

谢谢!

1 个答案:

答案 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的调用所生成的结果。

相关问题