#python #pyqt #qtableview #qabstractitemmodel #qabstracttablemodel
#python #pyqt #qtableview #qabstractitemmodel #qabstracttablemodel
Вопрос:
Я создал класс модели типа QAbstractTableModel, к которому я добавил ряд методов, как показано здесь:
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)
Во время выполнения, если подключено последовательное устройство, я хочу добавить в модель несколько дополнительных столбцов, но у меня возникают трудности с реализацией метода ‘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)
Ответ №1:
Должна быть реализована соответствующая функция «вставить столбцы», поскольку модель должна быть правильно обновлена, чтобы отразить фактическое количество столбцов, чтобы новые заголовки также отображались правильно.
Чтобы правильно добавлять столбцы, оба beginInsertColumn()
(перед добавлением новых данных столбца) и endInsertColumn()
(в конце операции) должны быть правильно вызваны.
Обычно для добавления дополнительных столбцов потребуется реализовать insertColumns()
, но, учитывая ситуацию и тот факт, что они все равно будут вызывать оба метода, нет необходимости делатьэто и пользовательская функция будут в порядке.
Следующее вставляет только один столбец, если вы хотите добавить больше столбцов сразу, просто убедитесь, что третий аргумент beginInsertColumns
правильно отражает это ( newColumn len(columnsToAdd)
) и что данные заголовка и новые пустые значения для массива соответствуют новому количеству столбцов.
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()
); - имена классов всегда должны быть с заглавной буквы, поэтому вам следует переименовать свой класс модели в R esultsModel; подробнее об этом читайте в официальном руководстве по стилю для кода Python;