如何向PyQT5表格传递实时数据并自动更新TableView
实现方案
核心思路
你需要先补全自定义QAbstractTableModel的更新方法,再将标签页的更新信号和模型方法绑定,就能自动完成数据传递和视图刷新,不需要额外处理标签页的特殊逻辑,Qt的信号槽机制天然支持跨组件通信。
步骤1:实现自定义表格模型
首先补全你已经创建的QAbstractTableModel子类,新增数据更新方法,内部主动触发视图刷新:
from PyQt5.QtCore import QAbstractTableModel, Qt, QModelIndex # 提前定义温度、功率通道数量 NUM_TEMPS = 8 NUM_POWERS = 4 class CustomTableModel(QAbstractTableModel): def __init__(self, parent=None): super().__init__(parent) # 内部存储数据源,第一行存温度、第二行存功率 self._data = [[None]*NUM_TEMPS, [None]*NUM_POWERS] self._vertical_headers = ["温度", "功率"] def rowCount(self, parent=QModelIndex()): return 2 if not parent.isValid() else 0 def columnCount(self, parent=QModelIndex()): return max(NUM_TEMPS, NUM_POWERS) if not parent.isValid() else 0 def data(self, index, role=Qt.DisplayRole): if not index.isValid() or role != Qt.DisplayRole: return None row, col = index.row(), index.column() if row == 0 and col < len(self._data[0]): return self._data[0][col] elif row == 1 and col < len(self._data[1]): return self._data[1][col] return None def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole: if orientation == Qt.Vertical: return self._vertical_headers[section] if section < len(self._vertical_headers) else None else: return f"通道{section+1}" return None # 对外暴露的更新数据方法,接收新的温度、功率数组 def update_data(self, new_temps, new_powers): # 更新内部存储的数据源 self._data[0] = new_temps.copy() self._data[1] = new_powers.copy() # 通知视图整个数据范围变更,自动刷新对应单元格 top_left = self.index(0, 0) bottom_right = self.index(self.rowCount()-1, self.columnCount()-1) self.dataChanged.emit(top_left, bottom_right, [Qt.DisplayRole])
步骤2:修改标签页代码
修正原代码的属性定义问题,完成信号与模型方法的绑定:
from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QTableView from PyQt5.QtCore import Signal class SummaryTableTab(QMainWindow): # 数据更新信号,携带温度、功率数组字典 _update_data = Signal(dict) def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle('Tables') # 实例可变属性统一在__init__中定义,避免多实例共享数据出错 self.temperatures = [None]*NUM_TEMPS self.powers = [None]*NUM_POWERS self.data = [self.temperatures, self.powers] # 基础布局初始化 central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(spacing=4, contentsMargins=(8,8,8,8)) central_widget.setLayout(layout) # 初始化表格视图、绑定自定义模型 self.table_view = QTableView() self.table_model = CustomTableModel() self.table_view.setModel(self.table_model) layout.addWidget(self.table_view) # 绑定更新信号到模型的更新方法,完成数据自动传递 self._update_data.connect(lambda data_dict: self.table_model.update_data(data_dict['temps'], data_dict['powers'])) def new_data(self, data): # 更新本地存储的温度数组 temperatures = data['Temperatures'] for i in range(len(temperatures)): self.temperatures[i] = temperatures[i] # 更新本地存储的功率数组 powers = data['Powers'] for i in range(len(powers)): self.powers[i] = powers[i] self.data = [self.temperatures, self.powers] # 发射信号触发模型更新、视图自动刷新 self._update_data.emit({ 'temps': self.temperatures, 'powers': self.powers, })
关键说明
- 模型的
dataChanged信号会通知视图只刷新变更的单元格,性能远高于全量重置模型 - 信号槽的绑定完全解耦了标签页数据更新和表格刷新的逻辑,后续如果要新增其他表格,只需要新增信号绑定即可
内容的提问来源于stack exchange,提问作者brbr9095
相关产品推荐
相关产品推荐

