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

如何在数据变更时全面更新QTableView?

QAbstractTableModel整体数据变更时刷新QTableView的方案

当底层数据出现插入行、删除行、修改行或多种情况并存的变更,且暂时无法追踪具体变更位置时,不需要逐个调用insertRows/deleteRows,可以通过模型的重置通知机制让视图全面刷新。

问题原因

你当前使用dataChanged信号只能通知视图单元格内容的变化,但无法触发视图对行/列数量变更的感知,所以插入新行后视图行数没更新,导致最后一行被截断。

解决方案

使用beginResetModel()和endResetModel()这一对方法:

  • 在修改底层数据前调用beginResetModel(),通知所有关联的视图:模型即将重置,暂停更新
  • 修改完数据后调用endResetModel(),通知视图模型已完成重置,此时视图会重新查询rowCount()、columnCount()以及所有单元格数据,实现全面刷新

修改后的代码示例

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt


class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self):
        super().__init__()
        self._data = [
            ("spam", "spam", "spam", "spam"),
            ("spam", "spam", "spam", "spam"),
            ("spam", "spam", "spam", "spam"),
        ]

    def headerData(self, section: int, orientation: Qt.Orientation, role=Qt.DisplayRole):
        if role == Qt.DisplayRole and orientation == Qt.Horizontal:
            return f"Foo {section + 1}"

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self._data)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return 4

    def refresh_data(self):
        # 通知模型即将重置
        self.beginResetModel()
        # 修改底层数据
        self._data.insert(0, ("ham", "ham", "ham", "ham"))
        # 通知模型重置完成,触发视图全面刷新
        self.endResetModel()


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.table = QtWidgets.QTableView()
        layout.addWidget(self.table)

        self.model = MyTableModel()
        self.table.setModel(self.model)

        update_data_button = QtWidgets.QPushButton("Update data")
        update_data_button.clicked.connect(self.model.refresh_data)
        layout.addWidget(update_data_button)


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

补充说明

  • 这种方式是全局刷新,会让视图重新加载所有数据,适合你暂时无法追踪细粒度变更的场景
  • 后续如果能实现细粒度变更追踪,再改用insertRows/deleteRows+dataChanged的组合,可以获得更好的性能和更流畅的视图更新效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:22