Search code examples
pythonmayapyside2qtableview

Cannot set header data with QTableView / custom table model


I am on Maya / PySide2 / Python 2.7

I cannot set the header data with a custom table model.

I tried this:

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()

afterwards I tried setting the header after setting the model like this:

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()

Both of them throwing no errors but column headers are not getting renamed, they stay as 1,2,3,4


Solution

  • When implementing an abstract model, all the required methods should be implemented, otherwise the default ones will be used. In the case of header labels, the fallback is the headerData() (which returns None in the default implementation) and setHeaderData(). The latter is important, as it always returns a bool value indicating whether the data has been set or not: the default behavior of abstract models is that no data is set, because the method must be implemented.

    In order to correctly implement both reading and writing of header data, you must override both methods:

    class TableModel(QtCore.QAbstractTableModel):
        def __init__(self, data):
            super(TableModel, self).__init__()
            
            self.horizontalHeaders = [''] * 4
    
            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)
    
        # ...