PyQt5中QSortFilterProxyModel变更时更新QStatusBar中的QWidgets
解决QSortFilterProxyModel变更时自动更新状态栏汇总值的问题
我完全懂你现在的卡点——好不容易把状态栏的列汇总做出来了,结果代理模型一过滤、排序,汇总值就停留在老数据上,没法自动更新对吧?其实核心就是你的汇总逻辑没跟上代理模型的变化节奏,咱们只要给代理模型的关键信号加个监听,就能解决这个问题。
为什么之前不自动更新?
QSortFilterProxyModel本质是个“数据中间商”,它会根据过滤/排序规则把原模型的数据转成QTableView显示的可见数据。但当这些规则变化、或者原模型数据更新时,代理模型会悄悄更新自己的数据集,可你的汇总代码根本不知道这事,自然不会重新计算。
具体解决步骤
1. 给代理模型的变化信号挂监听
在你的TBWindow类初始化的时候,把代理模型的几个核心变化信号和你的汇总更新方法绑定起来。这样每次代理模型的可见数据变了,就会自动触发汇总计算:
class TBWindow(QMainWindow): def __init__(self): super().__init__() # 假设你已经完成了这些初始化: # self.proxy_model = QSortFilterProxyModel(self) # self.table_view = QTableView(self) # self.table_view.setModel(self.proxy_model) # 把代理模型的关键信号连接到汇总更新方法 self.proxy_model.layoutChanged.connect(self.update_summary) self.proxy_model.dataChanged.connect(self.update_summary) self.proxy_model.rowsInserted.connect(self.update_summary) self.proxy_model.rowsRemoved.connect(self.update_summary) self.proxy_model.modelReset.connect(self.update_summary)
每个信号的作用:
layoutChanged:排序、过滤导致显示的行/列布局大变时触发(比如过滤后只剩几行)dataChanged:代理模型里的单元格数据修改时触发rowsInserted/rowsRemoved:代理模型新增或删除行时触发(比如原模型加了数据,代理同步)modelReset:代理模型完全重置时触发(比如换了原模型)
2. 汇总计算要基于代理模型
记住!一定要从代理模型里取数,而不是原模型,因为代理模型才是当前QTableView真正显示的数据。举个汇总某列总和的例子:
def update_summary(self): # 替换成你要汇总的列索引(从0开始计数) target_col = 2 total = 0.0 # 遍历代理模型的所有可见行 for row in range(self.proxy_model.rowCount()): # 获取当前行当前列的索引对象 idx = self.proxy_model.index(row, target_col) # 取出单元格数据 val = self.proxy_model.data(idx) # 处理非数值的情况(根据你的数据类型调整逻辑) try: if val is not None: total += float(val) except (ValueError, TypeError): # 如果不是可转换的数值,直接跳过 continue # 更新状态栏显示 self.statusBar().showMessage(f"当前列汇总值: {total:.2f}")
3. 可选优化:提升大数据场景性能
如果你的数据量特别大,每次全量遍历可能有点卡,可以做个小优化:
- 只在
layoutChanged和modelReset时全量计算总和 - 在
dataChanged时,只修改变更行对应的数值(需要先记录之前的总和,然后用新值减旧值更新总和)
这样既能保证准确性,又能减少不必要的计算。
内容的提问来源于stack exchange,提问作者New2coding
相关产品推荐
相关产品推荐

