Python 如何在运行时使用PYQT将新列插入qabstractable模型

Python 如何在运行时使用PYQT将新列插入qabstractable模型,python,pyqt,qtableview,qabstractitemmodel,qabstracttablemodel,Python,Pyqt,Qtableview,Qabstractitemmodel,Qabstracttablemodel,我创建了一个类型为QabStretctTableModel的模型类,并在其中添加了许多方法,如下所示: class resultsModel(QAbstractTableModel): def __init__(self, parent, headerData, arraydata, *args): QAbstractTableModel.__init__(self, parent, *args) self.arraydata = arraydata

我创建了一个类型为QabStretctTableModel的模型类,并在其中添加了许多方法,如下所示:

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)
必须实现适当的“插入列”功能,因为应正确更新模型以反映实际列数,以便正确显示新标题

为了正确添加列,应正确调用(在添加新列数据之前)和(在操作结束时)。
通常,添加更多的列需要实现,但是考虑到这种情况以及它们无论如何都会调用这两个方法的事实,没有必要这样做,自定义函数也可以

下面只插入一列,如果要一次添加更多列,只需确保
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()
  • 类名称应始终大写,因此应将模型类重命名为ResultsModel;阅读更多关于官方网站主题的文章