仅按 QSortFilterProxyModel 中的顶级项目过滤

Filter only by top-level items in QSortFilterProxyModel

我使用 QTreeView (PyQt 5) 来显示可用字体,效果很好。此外,我还有一个 QLineEdit 来使用 QSortFilterProxyModel.setFilterRegExp() 设置过滤器表达式, 似乎 也能很好地工作。

问题是我希望过滤器仅适用于顶级条目。我的树是这样显示的:

> Helvetica LT Std
  > Helvetica LT Std
      Italic
      Bold
      Regular
  > Helvetica LT Std Black
      Regular
      Italic

等这意味着当我输入 "Helv" 作为正则表达式时,所有其他字体都会被正确隐藏,但样式行也会被隐藏,因为它们中没有字体名称。

根据我的理解,我应该继承 QSortFilterProxyModel 并重写 filterAcceptsRow() 方法。如果该行是顶级条目,我会调用 super() 应用常规过滤,否则 return True 以避免过滤子元素。

我的问题是如何确定该行是否具有模型 invisibleRootItem() 以外的父项。可能它非常简单,但我仍然对架构感到困惑。

我有覆盖函数的接口:

def filterAcceptsRow(self, row, parent):

因为 row 只是一个整数,我不能用它做任何事情 (?) 而 parent 是一个 QModelIndex,它是一个非持久性引用,正确的?要回答的问题是"does this index point to the invisibleRootItem() of the source model?".

这个条件怎么查询?

感谢@vahancho 评论中的 我可以自己回答这个问题。

parent 参数已经 "knows" 了答案。在 PyQt 中(至少)如果父级是不可见的根,parent 将不会是 "null"(或 None)。它仍然是一个 QModelIndex 对象,但它的 isValid() 方法将 return False.

所以我的子类看起来像:

class FontFilterProxyModel(QSortFilterProxyModel):
    """Custom proxy model that ignores child elements in filtering"""

    def filterAcceptsRow(self, row, parent):
        if parent.isValid():
            # Do not apply the filter to child elements
            return True
        else:
            return super(FontFilterProxyModel, self).filterAcceptsRow(row, parent)