【发布时间】:2021-06-27 11:38:21
【问题描述】:
我有一个包含 6 列的表,其中包含 4 个不同的数据集。第 1 列和第 3 列每秒更新 10 次,第 2 列是静态列,在初始化时更新一次,然后不再更新。其他列的更新频率较低。我有点滞后 - 不可怕但绝对明显。
为了更新数据,我正在使用beingResetModel 和endResetModel。从文档中我了解到这将清除表格,然后为每个可见(行、列)调用数据。我正在更新很多我不需要的数据。
有没有一种方法可以指定我在更新函数中更改哪些列?是否可以只更新 column2 一次,然后再也不更新?
一个简化的模型如下所示,实际上数据结构不同,某些列的索引更复杂
class TableModel(PyQt5.QtCore.QAbstractTableModel):
def __init__(self, specs, length = 100000, parent=None):
super().__init__(parent)
self.default_length = length
self.initData()
def rowCount(self, parent=PyQt5.QtCore.QModelIndex()):
return self.default_length
def columnCount(self, parent=PyQt5.QtCore.QModelIndex()):
return 6
def update_d1(self, dat1):
#changes data in column 1 and 3
#data updates 10x per second
self.beginResetModel()
self.dat1 = dat1
self.endResetModel()
def update_d2(self, middle):
#changes data in column 2
#data updates once on initialisation, column doesnt change thereafter
self.beginResetModel()
self.middle = middle
self.endResetModel()
def update_d3(self, dat3):
#changes data in column 5
#data updates twice every second
self.beginResetModel()
self.dat3 = dat3
self.endResetModel()
def update_d4(self, dat4):
#changes column 0 and 4
# data updates sporadically
self.beginResetModel()
self.col0 = dat4['col0']
self.col4 = dat4['col4']
self.endResetModel()
def data(self, index, role):
if not index.isValid():
return
if role == PyQt5.QtCore.Qt.DisplayRole:
if index.row() < 0 or index.row() >= self.default_length:
return None
if index.column() == 0:
val = self.col0[index.row()]
return val
if index.column() == 4:
val = self.col4[index.row()]
return val
if index.column() == 2:
return self.middle[index.row()]
if index.column() == 1:
val = self.dat1['col1'][index.row()]
return val
if index.column() == 3:
val = self.dat1['col3'][index.row()]
return val
if index.column() == 5:
#print(self.volume_profile)
val = self.dat3[index.row()]
return val
编辑
如果我更改为以下内容,它将仅更新第一列中的第 100 行。
def update_d1(self, dat1):
col1_start_index = self.index(100, 0)
col1_end_index = self.index(100, 0)
self.data = data
self.dataChanged.emit(col1_start_index, col1_end_index)
如果我将结束索引设置为第 101 行,整个表格将再次更新,而不仅仅是 2 个单元格。提供两个索引的目的是什么?
def update_d1(self, dat1):
col1_start_index = self.index(100, 0)
col1_end_index = self.index(101, 0)
self.data = data
self.dataChanged.emit(col1_start_index, col1_end_index)
【问题讨论】:
-
如果你只是更新数据,模型大小没有改变,你为什么要使用
beingResetModel开始呢?您已经阅读了有关它的文档,很明显该功能不是您需要的,您是否考虑过阅读文档的其余部分来寻找什么你需要吗? -
感谢 musica,请参阅我对 dataChanged 的编辑。
-
这是所有项目视图的默认行为:只要 topLeft 和 bottomRight 索引不匹配,视图就会得到 full 更新(参见 source code。可能的解决方法可能是为模型创建一个自定义信号并将其连接到仅更新范围内索引的函数。
-
自定义信号的效率是否等同于循环开始和结束索引并为每个索引发出 dataChanged?
-
理论上不会:这仅取决于您如何发出这些信号。如果它们在同一个事件循环中发出(简化,
dataChange信号都是从同一个函数调用发送的,包括任何递归级别)它不会改变那么多:结果是该视图将为 dataChanged 索引的每个visualRect安排更新。您可以尝试通过“分组”所有更改的索引并使用这些索引发出信号来进行某种程度的优化,然后在连接的视图函数中使用visualRect创建一个包含所有这些索引矩形的 QRegion。
标签: python qt user-interface pyqt5 pyside