Search code examples
pythonqtpyqt5pysidepyside2

How to change QTableView text color using QItemDelegate?


I have created subclassed QItemDelegate and redefined the paint method. I have tried

painter.setPen(QtGui.QColor('#FFFFFF'))

which doesnt work. How do I change the text color?

As a side note I tried to color the background by calling painter.setBackground(color) which also doesnt work. How are these methods intended to be used?

class ItemDelegate(QtWidgets.QItemDelegate):
    def __init__(self, parent):
        QtWidgets.QItemDelegate.__init__(self, parent)
        self.parent = parent


    def paint(self, painter, option, index):
        item = index.data(QtCore.Qt.DisplayRole)
        #print(item)
        print(dir(painter))
        if index.column() == 1:
            color = QtGui.QColor('#34ebc6')
        elif index.column() == 2:
            color = QtGui.QColor('#FFFFFF')
        elif index.column() == 3:
            color = QtGui.QColor('#9546c7')
        else:
            color = QtGui.QColor('#FFFFFF')
        painter.fillRect(option.rect, color)
        super(ItemDelegate, self).paint(painter, option, index)

Solution

  • You have to override the drawDisplay method where you have to change the values of the QPalette::Text and QPalette::HighlightedText roles of the palette:

    class ItemDelegate(QtWidgets.QItemDelegate):
        def paint(self, painter, option, index):
            color = QtGui.QColor("#FFFFFF")
            if index.column() == 1:
                color = QtGui.QColor("#34ebc6")
            elif index.column() == 2:
                color = QtGui.QColor("#FFFFFF")
            elif index.column() == 3:
                color = QtGui.QColor("#9546c7")
            painter._color = color
    
            super(ItemDelegate, self).paint(painter, option, index)
    
        def drawDisplay(self, painter, option, rect, text):
            color = painter._color
            opt = QtWidgets.QStyleOptionViewItem(option)
            cg = (
                QtGui.QPalette.Normal
                if opt.state & QtWidgets.QStyle.State_Enabled
                else QtGui.QPalette.Disabled
            )
            if opt.state & QtWidgets.QStyle.State_Selected:
                opt.palette.setColor(cg, QtGui.QPalette.HighlightedText, color)
            opt.palette.setColor(cg, QtGui.QPalette.Text, color)
            super(ItemDelegate, self).drawDisplay(painter, opt, rect, text)
    

    With QStyledItemDelegate it is easier since you only need to override the initStyleOption method:

    class ItemDelegate(QtWidgets.QStyledItemDelegate):
        def initStyleOption(self, option, index):
            super(ItemDelegate, self).initStyleOption(option, index)
    
            color = QtGui.QColor("#FFFFFF")
    
            if index.column() == 1:
                color = QtGui.QColor("#34ebc6")
            elif index.column() == 2:
                color = QtGui.QColor("#FFFFFF")
            elif index.column() == 3:
                color = QtGui.QColor("#9546c7")
    
            cg = (
                QtGui.QPalette.Normal
                if option.state & QtWidgets.QStyle.State_Enabled
                else QtGui.QPalette.Disabled
            )
            if option.state & QtWidgets.QStyle.State_Selected:
                option.palette.setColor(cg, QtGui.QPalette.HighlightedText, color)
    
            option.palette.setBrush(QtGui.QPalette.Text, color)