首页 > 解决方案 > 仅按 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()如果该行是顶级条目,我会调用应用常规过滤,否则返回True以避免过滤子元素。

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

我有覆盖功能的接口:

def filterAcceptsRow(self, row, parent):

row只是一个整数,我不能用它做任何事情(?)并且parent是 a QModelIndex,这是一个非持久性引用,对吧?要回答的问题是“这个索引是否指向invisibleRootItem()源模型的?”。

我怎么能问这种情况?

标签: pythonpyqtpyqt5qtreeviewqsortfilterproxymodel

解决方案


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

论证已经“parent知道”了答案。在 PyQt 中(至少)parent不会是“null”(或None),如果父级是不可见的根。它仍然是一个QModelIndex对象,但它的isValid()方法将返回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)

推荐阅读