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

Python定时刷新QTableView实现QSortFilterProxyModel持久过滤

问题根因

你遇到的定时刷新后过滤失效问题,核心是代码逻辑把一次性初始化操作放到了周期执行的刷新方法里:

  • 每次updateAccountTable触发时都会新建一个全新的mysortingproxy实例,新实例默认过滤规则为空,自然不会保留之前的过滤状态
  • 每次刷新都重复给输入框绑定textChanged信号,运行时间长了会出现一次输入触发多次过滤的性能问题
  • 每次刷新都重新给表格视图绑定模型,完全属于冗余操作,视图只需要在初始化时绑定一次模型即可,后续数据变更通过模型的信号通知视图刷新。
修复步骤

1. 把模型、代理、信号绑定逻辑移到窗口初始化阶段

所有只需要执行一次的逻辑,全部放到MainUi的构造函数中,不要放到周期刷新的方法里:

class MainUi(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # 省略其他界面初始化代码...

        # 初始化源数据模型,仅创建一次
        self.accountTableModel = AccountTableModel(self.data, self.scalping, self)
        # 初始化自定义排序过滤代理,仅创建一次
        self.proxyModel = mysortingproxy(self)
        self.proxyModel.setFilterKeyColumn(0)  # 指定第一列为过滤列
        self.proxyModel.setSourceModel(self.accountTableModel)
        # 给表格视图绑定模型,仅设置一次
        self.tableView_Account.setModel(self.proxyModel)
        self.tableView_Account.setSortingEnabled(True)
        self.tableView_Account.verticalHeader().setVisible(False)
        # 绑定过滤输入框信号,仅绑定一次
        # 普通文本匹配推荐用setFilterFixedString性能更好,需要正则匹配再换setFilterRegExp
        self.lineEdit_Find.textChanged.connect(self.proxyModel.setFilterFixedString)

2. 改造周期刷新方法,仅更新源模型数据

把updateAccountTable里所有重建模型、代理、绑定信号的代码全部删除,只保留数据更新逻辑,不要新建任何模型实例:

def updateAccountTable(self):
    # 仅更新源模型内部存储的数据,不要新建模型/代理实例
    self.accountTableModel.updateData(self.data, self.scalping)

给自定义的AccountTableModel新增数据更新方法,更新内部数据后通知视图刷新,代理模型会自动复用已有的过滤、排序规则:

class AccountTableModel(QAbstractTableModel):
    # 省略你已实现的rowCount/columnCount/data等方法...
    def updateData(self, new_data, new_scalping):
        # 更新内部持有的数据引用
        self.data = new_data
        self.scalping = new_scalping
        # 通知视图数据已变更,触发界面重绘、代理重新过滤排序
        self.layoutChanged.emit()

3. 特殊场景兼容方案

如果你的业务场景确实需要每次刷新重建源模型(比如数据列结构会动态变化),那重建代理后必须手动把当前输入框的过滤值重新设置给新代理,否则新代理默认过滤规则为空:

# 不推荐,性能比复用模型差,仅作为兼容方案
def updateAccountTable(self):
    self.accountTableModel = AccountTableModel(self.data, self.scalping)
    proxyModel = mysortingproxy()
    proxyModel.setFilterKeyColumn(0)
    # 手动把当前输入框的过滤值设置给新代理
    proxyModel.setFilterFixedString(self.lineEdit_Find.text())
    proxyModel.setSourceModel(self.accountTableModel)
    self.tableView_Account.setModel(proxyModel)
    self.tableView_Account.setSortingEnabled(True)
    self.tableView_Account.verticalHeader().setVisible(False)

注意用这个方案必须先断开之前的信号连接,否则会出现信号重复绑定问题,优先选择第一种复用模型的方案。

内容的提问来源于stack exchange,提问作者Stéphane REY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:18:16