Как управлять цветом фона элементов QTableView

Это data() исходной модели, который устанавливает каждый из цветов фона индексов QTableView на зеленый, если номер строки индекса четный, и на синий, если он нечетный.

введите здесь описание изображения

Затем модель Proxy отфильтровывает каждый третий индекс. Таким образом, полученные цвета неупорядочены.

Проблема в том, что цвета фона назначаются в исходной модели до того, как индексы будут отфильтрованы прокси-моделью.

Вот исходный код:

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

person alphanumeric    schedule 18.01.2015    source источник


Ответы (1)


Вместо того, чтобы полагаться на функциональность метода data() исходной модели if Qt.BackgroundColorRole:, установите tableviewA.setAlternatingRowColors(True) в True. Он прекрасно работает с CSS. Полностью работающее решение размещено ниже (обратите внимание, что Qt.BackgroundColorRole закомментировано. В противном случае оно будет иметь приоритет над CSS):

введите здесь описание изображения

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_()) 
person alphanumeric    schedule 18.01.2015
comment
Можно ли установить один цвет для строк, которые выше 10, например, а затем остальные не тронуты (т.е. фон первых 10 строк белый)? Спасибо, что дали мне знать. - person New2coding; 24.11.2018
comment
NVM, разобрался, реализация метода данных в моем случае должна быть такой: если role == Qt.BackgroundColorRole и self.r не None: bgColor=QColor(Qt.blue) if index.row() › self. r: вернуть QVariant(QColor(bgColor)) - person New2coding; 24.11.2018