Как изменить цвет фона ячейки в QTableWidget?

Разрабатывал приложение, в котором такая проблема: у меня есть QTableWidget, в нем есть ячейки, в которых лежат виджеты (мои самописные) добавленные через QTableWidget::setCellWidget()

Мне нужно сделать так, чтобы каждая строка имела свой цвет фона (например первая строка - красный, вторая строка - синий и т.д).

Как я понял, я не могу задать background-color для всей строки, так что я делаю цвет фона для каждой отдельной ячейки.

Но есть проблема: там, где в ячейке находится обычный текст (в QTableWidgetItem, я просто задаю цвет фона для каждого элемента: setData(Qt::BackgroundRole, QColor("#ABCBCA"));), а вот с ячейками где лежат мои виджеты, дела по сложнее:

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

В последних двух столбцах лежат два виджета, в них лежат другие виджеты, я ожидаю примерно такого поведения, пустое место в ячейке (где видимо лежит пустое место от моего виджета) должно окраситься в выбранный мной цвет, а внутренние элементы (кнопки, поля ввода и т.п.) остаться не тронутыми. Но как бы я не применял стили, они либо не работают, либо дают примерно такой результат:

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

то есть эффект совершенно противоположный (меняется всё, кроме фона ячейки), от сюда у меня вопрос:

Как применить изменить цвет ячейки, не меняя внутренних элементов?

Заранее спасибо


Ответы (2 шт):

Автор решения: Юрий

Думаю в Вашем случае придется отказаться от QTableWidget и использовать QTableView в связке с QAbstractTableModel. Также придется создать класс, наследующий QAbstractItemDelegate и реализующий виртуальный метод paint: https://doc.qt.io/qt-5/qabstractitemdelegate.html#details

В этом методе как раз и будет реализовано отображение ячейки в том виде, в котором Вам необходимо.

А потом этот кастомный делегат передавать вьюшке методом setItemDelegateForColumn: https://doc.qt.io/qt-5/qabstractitemview.html#setItemDelegateForColumn

→ Ссылка
Автор решения: S. Nick

Не очень хорошо, что вы не предоставляете минимально-воспроизводимый пример, который демонстрирует проблему.

Но так как поступил ответ с сомнениями возможной реализации, пришлось попробовать сделать и я увидел вашу задачу так:

import sys
from PyQt5.Qt import *


class Widget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
       
        self._widget = QWidget() 
        self._widget.setObjectName("_widget")
        self.setStyleSheet("#_widget {background-color: #FFCB00;}")
        
        self._label = QLabel()
        self._line = QLineEdit(placeholderText="Введите text")
        self._button = QPushButton("Button")
        self._button.clicked.connect(
            lambda: print(f'label: {self._label.text()}, lineEdit: {self._line.text()}')
        )

        lay = QVBoxLayout(self._widget) 
        lay.addWidget(self.label)
        lay.addWidget(self.line)
        lay.addWidget(self.button)
        
        layout = QHBoxLayout(self)
        layout.addWidget(self._widget)

    @property
    def label(self):
        return self._label

    @property
    def line(self):
        return self._line
        
    @property
    def button(self):
        return self._button
        

class Main(QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        
        self.tableWidget = QTableWidget(5, 5)
        self.tableWidget.setMinimumSize(600, 320)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        for row in range(3):
            for column in range(4):
                widget = Widget(self)
                widget.label.setText("row " + str(row))
                self.tableWidget.setCellWidget(row, column, widget)
            self.tableWidget.setItem(row, column+1, QTableWidgetItem(f'row={row}, column={column+1}'))  
            
        self.tableWidget.setItem(row+1, 0, QTableWidgetItem('Hello')) 
        self.tableWidget.setItem(row+1, 1, QTableWidgetItem('World'))  
        self.tableWidget.setItem(row+2, 0, QTableWidgetItem('Hello')) 
        self.tableWidget.setItem(row+2, 1, QTableWidgetItem('World'))         
        self.tableWidget.resizeRowsToContents()

        for row in range(self.tableWidget.rowCount()):
            for column in range(self.tableWidget.columnCount()):
                widget = self.tableWidget.cellWidget(row, column)
                if isinstance(widget, QWidget):
                    lineedit = widget.findChild(QLineEdit)
                    if lineedit is not None:
                        lineedit.setText("some text")
  
        self.setStyleSheet("""
            QTableWidget {
                background-color: #55FF77;  
                color: blue;             
            }
        """)
        
        mainLayout = QVBoxLayout(self.centralWidget)
        mainLayout.addWidget(self.tableWidget)
        mainLayout.addStretch(1) 
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    
    app.setStyle("Fusion")
    palette = QPalette()
    palette.setColor(QPalette.AlternateBase, QColor(253, 53, 53))
    app.setPalette(palette)
    
    w = Main()
    w.resize(640, 480)
    w.show()
    sys.exit(app.exec())

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

→ Ссылка