alphanumeric
alphanumeric

Reputation: 19329

How to control QTableView Items Background color

It is the source model's data() that sets each of `QTableView's indexes background colors to a green if the index's row number is even and to a blue if it is odd.

enter image description here

Then the Proxy model filters out every third index. So the resulted colors are all unordered.

The problem is that the background colors are assigned in a Source Model before the Indexes get filtered by the Proxy model.

Here is the source code:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

class MyTableModel(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = [i for i in range(90)]

    def rowCount(self, parent):
        return len(self.items)       
    def columnCount(self, parent):
        return 1

    def data(self, index, role):
        if not index.isValid():
            return QVariant()

        row=index.row()
        column=index.column()

        if role == Qt.DisplayRole:
            if row<len(self.items):
                return QVariant(self.items[row])
            else:
                return QVariant()

        if role==Qt.BackgroundColorRole:
            if row%2: bgColor=QColor(Qt.green)
            else: bgColor=QColor(Qt.blue)        
            return QVariant(QColor(bgColor))


class Proxy01(QSortFilterProxyModel):
    def __init__(self):
        super(Proxy01, self).__init__()

    def filterAcceptsRow(self, row, parent):
        if row%3: return True
        else: return False

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        self.tablemodel=MyTableModel(self)               

        self.proxy1=Proxy01()
        self.proxy1.setSourceModel(self.tablemodel)

        tableviewA=QTableView(self) 
        tableviewA.setModel(self.proxy1)
        tableviewA.setSortingEnabled(True) 
        tableviewA.horizontalHeader().setSortIndicator(0, Qt.AscendingOrder)
        tableviewA.horizontalHeader().setStretchLastSection(True)

        layout = QVBoxLayout(self)
        layout.addWidget(tableviewA)

        self.setLayout(layout)

    def test(self, arg):
        print arg

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_()) 

Upvotes: 1

Views: 6604

Answers (1)

alphanumeric
alphanumeric

Reputation: 19329

Instead of relying on source model's data()'s if Qt.BackgroundColorRole: method's functionality set tableviewA.setAlternatingRowColors(True) to True. It works beautifully with CSS. A fully working solution is posted below (please note that Qt.BackgroundColorRole has been commented out. Otherwise it would take precedence over the CSS):

enter image description here

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

class MyTableModel(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = [i for i in range(90)]

    def rowCount(self, parent):
        return len(self.items)       
    def columnCount(self, parent):
        return 1

    def data(self, index, role):
        if not index.isValid():
            return QVariant()

        row=index.row()
        column=index.column()

        if role == Qt.DisplayRole:
            if row<len(self.items):
                return QVariant(self.items[row])
            else:
                return QVariant()

        # if role==Qt.BackgroundColorRole:
        #     if row%2: bgColor=QColor(Qt.green)
        #     else: bgColor=QColor(Qt.blue)        
        #     return QVariant(QColor(bgColor))


class Proxy01(QSortFilterProxyModel):
    def __init__(self):
        super(Proxy01, self).__init__()

    def filterAcceptsRow(self, row, parent):
        if row%3: return True
        else: return False

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        self.tablemodel=MyTableModel(self)               

        self.proxy1=Proxy01()
        self.proxy1.setSourceModel(self.tablemodel)

        tableviewA=QTableView(self) 
        tableviewA.setModel(self.proxy1)
        tableviewA.setSortingEnabled(True) 
        tableviewA.horizontalHeader().setSortIndicator(0, Qt.AscendingOrder)
        tableviewA.horizontalHeader().setStretchLastSection(True)
        tableviewA.setAlternatingRowColors(True)
        tableviewA.setStyleSheet("alternate-background-color: yellow; background-color: red;");

        layout = QVBoxLayout(self)
        layout.addWidget(tableviewA)

        self.setLayout(layout)

    def test(self, arg):
        print arg

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_()) 

Upvotes: 4

Related Questions