You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

旧版Qt如何让filterAcceptsRow不过滤含匹配子项的父节点?

旧版Qt树形视图递归过滤实现方案

你需要的核心逻辑是在filterAcceptsRow中增加子节点的递归匹配校验:只要当前节点本身匹配,或是存在任意子节点匹配,就返回True保留当前节点,就可以解决父节点过滤导致子节点无法展示的问题。
ui

基础实现(不关联展开状态,全量递归检查)

直接修改你的过滤代理代码即可:

def filterAcceptsRow(self, source_row, source_parent_index):
    model = self.sourceModel()
    source_index = model.index(source_row, 0, source_parent_index)

    # 检查当前节点本身是否匹配过滤规则
    d = model.searchableData(source_index)
    if self.isVisible(d):
        return True

    # 递归检查所有子节点是否存在匹配项,有匹配则保留当前父节点
    if model.hasChildren(source_index):
        child_row_count = model.rowCount(source_index)
        for child_row in range(child_row_count):
            if self.filterAcceptsRow(child_row, source_index):
                return True

    # 自身不匹配且无匹配子节点,隐藏该节点
    return False

结合节点展开状态的实现

如果你需要仅对已展开的节点检查子节点,未展开的节点仅校验自身,需要额外维护已展开节点的索引集合:

  1. 给过滤代理类添加成员变量存储已展开的源模型索引
  2. 绑定树形视图的展开/收起信号,实时更新索引集合
  3. 调整过滤逻辑,仅已展开节点才递归检查子节点
# 视图初始化时绑定信号(proxy为你的过滤代理实例)
tree_view.expanded.connect(lambda proxy_idx: 
    proxy.expanded_indexes.add(tree_view.model().mapToSource(proxy_idx))
)
tree_view.collapsed.connect(lambda proxy_idx: 
    proxy.expanded_indexes.discard(tree_view.model().mapToSource(proxy_idx))
)

# 过滤代理中的实现
class YourFilterProxy(QSortFilterProxyModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.expanded_indexes = set() # 存储已展开的源模型索引

    def filterAcceptsRow(self, source_row, source_parent_index):
        model = self.sourceModel()
        source_index = model.index(source_row, 0, source_parent_index)

        # 检查当前节点本身是否匹配
        d = model.searchableData(source_index)
        if self.isVisible(d):
            return True

        # 仅已展开的节点才检查子节点匹配情况
        if model.hasChildren(source_index) and source_index in self.expanded_indexes:
            child_row_count = model.rowCount(source_index)
            for child_row in range(child_row_count):
                if self.filterAcceptsRow(child_row, source_index):
                    return True

        return False

注意事项

  • 如果树的节点数量极多、层级很深,可以给递归结果加缓存提升过滤性能
  • 每次修改过滤关键词后需要调用invalidateFilter()触发全量重过滤
  • 该实现完全兼容旧版Qt,效果和新版setRecursiveFilteringEnabled(true)一致

内容的提问来源于stack exchange,提问作者pawel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:06:03