如何使用 PYQT 在运行时向 QAbstractTable 模型插入新列
How to insert a new column to a QAbstractTable Model at runtime using PYQT
我创建了一个类型为 QAbstractTableModel 的模型 class,我向其中添加了许多方法,如下所示:
class resultsModel(QAbstractTableModel):
def __init__(self, parent, headerData, arraydata, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.arraydata = arraydata
self.headerdata = headerData #['Timestamp', 'Force (N)', 'Diplacement (mm)']
def rowCount(self, parent):
return len(self.arraydata)
def columnCount(self, parent):
if len(self.arraydata) > 0:
return len(self.arraydata[0])
return 0
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headerdata[col]
return None
#Make table cells non-editable
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def data(self, index, role):
if not index.isValid():
return None
value = self.arraydata[index.row()][index.column()]
if role == Qt.EditRole:
return value
elif role == Qt.DisplayRole:
return value
def setData(self, index, value, role):
if not index.isValid():
return None
row = index.row()
column = index.column()
self.arraydata[row][column] = value
self.dataChanged.emit(index, index)
return True
def setHeaderData(self, col, orientation, value, role):
if role != Qt.DisplayRole or orientation != Qt.Horizontal:
return False
self.headerdata[col] = value
result = self.headerdata[col]
if result:
self.headerDataChanged.emit(orientation, col, col)
return result
当应用程序启动时,我使用了一个带有上面模型的 QTableview:
resultsHeaders = ['Timestamp', 'Force (N)', 'Diplacement (mm)']
resultsData = [['','','']]
self.resultsTableModel = resultsModel(self, resultsHeaders, resultsData)
self.resultsTable = QTableView()
self.resultsTable.setModel(self.resultsTableModel)
在运行时,如果连接了串行设备,我想向模型添加一些额外的列,但是在添加新的 [=21= 之前,我很难为模型实现 'insertColumns' 方法] 值。
#insert columns
???
#update header values
for i in range(len(resultsHeaders)):
self.resultsTable.model().setHeaderData(i, Qt.Horizontal, str(resultsHeaders[int(i)]), Qt.DisplayRole)
必须实施适当的“插入列”功能,因为应正确更新模型以反映实际列数,以便新的 header 也能正确显示。
为了正确添加列,beginInsertColumn()
(before adding new column data) and endInsertColumn()
(在操作结束时)都应该被正确调用。
通常情况下,添加更多的列需要实现 insertColumns()
,但考虑到这种情况以及它们无论如何都会调用这两种方法的事实,没有必要这样做,自定义函数就可以了。
下面只插入一列,如果你想一次添加更多列,只需确保 beginInsertColumns
的第三个参数正确反映了 (newColumn + len(columnsToAdd)
) 并且 header 数组的数据和新的空值对应于新的列数。
class ResultsModel(QAbstractTableModel):
# ...
def addColumn(self, name):
newColumn = self.columnCount()
self.beginInsertColumns(QModelIndex(), newColumn, newColumn)
self.headerdata.append(name)
for row in self.arraydata:
row.append('')
self.endInsertColumns()
# ...
class Whatever(QWidget):
# ...
def addColumn(self):
name = 'New column {}'.format(self.resultsTableModel.columnCount())
self.resultsTableModel.addColumn(name)
注意:
rowCount()
和 columnCount()
都应该像基本实现一样有一个默认关键字 parent
参数(公认的做法涉及 parent=QModelIndex()
);
- class 名称应 始终 大写,因此您应将模型 class 重命名为 ResultsModel ;在官方 Style Guide for Python Code;
上阅读更多关于该主题的内容
我创建了一个类型为 QAbstractTableModel 的模型 class,我向其中添加了许多方法,如下所示:
class resultsModel(QAbstractTableModel):
def __init__(self, parent, headerData, arraydata, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.arraydata = arraydata
self.headerdata = headerData #['Timestamp', 'Force (N)', 'Diplacement (mm)']
def rowCount(self, parent):
return len(self.arraydata)
def columnCount(self, parent):
if len(self.arraydata) > 0:
return len(self.arraydata[0])
return 0
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.headerdata[col]
return None
#Make table cells non-editable
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
def data(self, index, role):
if not index.isValid():
return None
value = self.arraydata[index.row()][index.column()]
if role == Qt.EditRole:
return value
elif role == Qt.DisplayRole:
return value
def setData(self, index, value, role):
if not index.isValid():
return None
row = index.row()
column = index.column()
self.arraydata[row][column] = value
self.dataChanged.emit(index, index)
return True
def setHeaderData(self, col, orientation, value, role):
if role != Qt.DisplayRole or orientation != Qt.Horizontal:
return False
self.headerdata[col] = value
result = self.headerdata[col]
if result:
self.headerDataChanged.emit(orientation, col, col)
return result
当应用程序启动时,我使用了一个带有上面模型的 QTableview:
resultsHeaders = ['Timestamp', 'Force (N)', 'Diplacement (mm)']
resultsData = [['','','']]
self.resultsTableModel = resultsModel(self, resultsHeaders, resultsData)
self.resultsTable = QTableView()
self.resultsTable.setModel(self.resultsTableModel)
在运行时,如果连接了串行设备,我想向模型添加一些额外的列,但是在添加新的 [=21= 之前,我很难为模型实现 'insertColumns' 方法] 值。
#insert columns
???
#update header values
for i in range(len(resultsHeaders)):
self.resultsTable.model().setHeaderData(i, Qt.Horizontal, str(resultsHeaders[int(i)]), Qt.DisplayRole)
必须实施适当的“插入列”功能,因为应正确更新模型以反映实际列数,以便新的 header 也能正确显示。
为了正确添加列,beginInsertColumn()
(before adding new column data) and endInsertColumn()
(在操作结束时)都应该被正确调用。
通常情况下,添加更多的列需要实现 insertColumns()
,但考虑到这种情况以及它们无论如何都会调用这两种方法的事实,没有必要这样做,自定义函数就可以了。
下面只插入一列,如果你想一次添加更多列,只需确保 beginInsertColumns
的第三个参数正确反映了 (newColumn + len(columnsToAdd)
) 并且 header 数组的数据和新的空值对应于新的列数。
class ResultsModel(QAbstractTableModel):
# ...
def addColumn(self, name):
newColumn = self.columnCount()
self.beginInsertColumns(QModelIndex(), newColumn, newColumn)
self.headerdata.append(name)
for row in self.arraydata:
row.append('')
self.endInsertColumns()
# ...
class Whatever(QWidget):
# ...
def addColumn(self):
name = 'New column {}'.format(self.resultsTableModel.columnCount())
self.resultsTableModel.addColumn(name)
注意:
rowCount()
和columnCount()
都应该像基本实现一样有一个默认关键字parent
参数(公认的做法涉及parent=QModelIndex()
);- class 名称应 始终 大写,因此您应将模型 class 重命名为 ResultsModel ;在官方 Style Guide for Python Code; 上阅读更多关于该主题的内容