无法使用 QTableView/自定义 table 模型设置 header 数据

Cannot set header data with QTableView / custom table model

我在 Maya/PySide2/Python2.7

我无法使用自定义 table 模型设置 header 数据。

我试过这个:

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt


class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        
        self.setHeaderData(0, Qt.Horizontal, "Driver")
        self.setHeaderData(1, Qt.Horizontal, "Range")
        self.setHeaderData(2, Qt.Horizontal, "Driven")
        self.setHeaderData(3, Qt.Horizontal, "Range")
        
        self._data = data

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

    def rowCount(self, index):
        return len(self._data)

    def columnCount(self, index):
        return 4
        
    def addRow(self, row):
        self._data.append(row)
        self.layoutChanged.emit()  

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.table = QtWidgets.QTableView()

        data = [
        [
            "firstData", "[0, 100]", "secondData", "[0, 1]"],
        ]

        self.model = TableModel(data)
        self.table.setModel(self.model)
        
        self.setCentralWidget(self.table)

window=MainWindow()
window.show()

之后我尝试在设置模型后设置 header:

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.table = QtWidgets.QTableView()

        data = [
        [
            "firstData", "[0, 100]", "secondData", "[0, 1]"],
        ]

        self.model = TableModel(data)
        self.table.setModel(self.model)
        
        self.model.setHeaderData(0, Qt.Horizontal, "Driver")
        self.model.setHeaderData(1, Qt.Horizontal, "Range")
        self.model.setHeaderData(2, Qt.Horizontal, "Driven")
        self.model.setHeaderData(3, Qt.Horizontal, "Range")
        
        self.setCentralWidget(self.table)

window=MainWindow()
window.show()

它们都没有抛出错误,但是 header 列没有重命名,它们保持为 1,2,3,4

实现抽象模型时,必须实现所有需要的方法,否则将使用默认方法。在 header 标签的情况下,回退是 headerData() (which returns None in the default implementation) and setHeaderData()。后者很重要,因为它总是 returns 一个 bool 值,指示数据是否已设置:抽象模型的默认行为是没有设置数据,因为必须实现该方法。

为了正确实现对header数据的读写,必须重写这两个方法:

class TableModel(QtCore.QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        
        <b>self.horizontalHeaders = [''] * 4</b>

        self.setHeaderData(0, Qt.Horizontal, "Driver")
        self.setHeaderData(1, Qt.Horizontal, "Range")
        self.setHeaderData(2, Qt.Horizontal, "Driven")
        self.setHeaderData(3, Qt.Horizontal, "Range")
        
        self._data = data

    def setHeaderData(self, section, orientation, data, role=Qt.EditRole):
        if orientation == Qt.Horizontal and role in (Qt.DisplayRole, Qt.EditRole):
            try:
                self.horizontalHeaders[section] = data
                return True
            except:
                return False
        return super().setHeaderData(section, orientation, data, role)

    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            try:
                return self.horizontalHeaders[section]
            except:
                pass
        return super().headerData(section, orientation, role)

    # ...