Как изменить цвет одной ячейки заголовка (vertical header) у QTableView?

Рейтинг: 1Ответов: 1Опубликовано: 08.05.2023

Не получается изменить цвет одной ячейки заголовка QHeaderView (vertical header) у QTableView.

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QColor
from PyQt5.QtWidgets import QApplication, QHeaderView, QTableView, QMainWindow,  QAction, QComboBox, QTabWidget, QLabel


class FreezeTableWidget(QTableView):
    def __init__(self, model):
        super().__init__()
        self.setModel(model)
        self.frozenTableView = QTableView(self)
        self.init()
        self.frozenTableView.horizontalScrollBar().valueChanged.connect(
            self.horizontalScrollBar().setValue)
        self.horizontalScrollBar().valueChanged.connect(
            self.frozenTableView.horizontalScrollBar().setValue)
    def init(self):
        self.frozenTableView.setModel(self.model())
        self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
        self.frozenTableView.setFocusPolicy(Qt.NoFocus)
        self.frozenTableView.horizontalHeader().hide()
        self.frozenTableView.verticalHeader().setStyleSheet('''
                            QHeaderView {border: 2px solid;
                             selection-background-color: #3399FF;
                                         font: Bold;
                                         font-size: 20px;
                                         font-family: Times New Roman;
                            }
                        ''')
        self.frozenTableView.verticalHeader().verticalOffset()
        self.frozenTableView.verticalHeader().setFixedWidth(150)
        self.frozenTableView.verticalHeader().setSectionResizeMode(
            QHeaderView.Fixed)
        self.viewport().stackUnder(self.frozenTableView)
        self.frozenTableView.setStyleSheet('''
            QTableView { border: none;
                         background-color: white;
                         selection-background-color: #3399FF;
                         font: Bold;
                         text-align: center;
            }
        ''')
        self.frozenTableView.setSelectionModel(self.selectionModel())
        for row1 in range(4, self.model().rowCount()):
            self.frozenTableView.setRowHidden(row1, True)
        self.frozenTableView.setColumnWidth(0, self.columnWidth(0))
        self.frozenTableView.setHorizontalScrollBarPolicy(1)
        self.frozenTableView.setVerticalScrollBarPolicy(1)
        self.frozenTableView.show()
        self.updateFrozenTableGeometry()
        self.setHorizontalScrollMode(self.ScrollPerPixel)
        self.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setHorizontalScrollMode(self.ScrollPerPixel)
    def updateSectionWidth(self, logicalIndex, newSize):
        self.frozenTableView.setColumnWidth(logicalIndex, newSize)
    def resizeEvent(self, event):
        super(FreezeTableWidget, self).resizeEvent(event)
        self.updateFrozenTableGeometry()
    def updateFrozenTableGeometry(self):
        self.frozenTableView.setGeometry(
            self.frameWidth(),
            self.horizontalHeader().height(),
            self.viewport().width() + 150,
            4 * self.rowHeight(0))

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.createToolBars()
        model = QStandardItemModel()
        header = ["Ввод1", "Ввод2", "Ввод3", "Ввод4", "Ввод5", "Ввод6", "Ввод7", "Ввод8", "Ввод9"]
        model.setVerticalHeaderLabels(header)
        widht_mon = 700
        height_mon = 500

        self.tableView = FreezeTableWidget(model)
        self.tableView.verticalHeader().setFixedWidth(150)
        self.tableView.horizontalHeader().hide()
        self.tabwidget2 = QTabWidget()
        self.setCentralWidget(self.tabwidget2)
        self.tabwidget2.insertTab(0, self.tableView, "ВВОД ДАННЫХ")
        self.resize(widht_mon, height_mon)
        self.tableView.verticalHeader().setStyleSheet('''
                    QHeaderView { border: 2px solid;
                    selection-background-color: #3399FF;
                                 font: Bold;
                                 font-size: 20px;
                                 font-family: Times New Roman;
                    }
                ''')
        self.newAction.triggered.connect(self.bgrbom)
        column_count1 = model.columnCount()
        i = 0
        while i < column_count1:
            comb_bgrjwu_bgrofj1_table = QComboBox()
            comb_bgrjwu_bgrofj1_table.wheelEvent = lambda event: None
            comb_bgrjwu_bgrofj1_table.addItems(["1", "2", "3"])
            comb_bgrjwu_bgrofj1_table_site = self.tableView.model().index(5, i)
            comb_bgrjwu_bgrofj1_table.setCurrentIndex(int(self.tableView.model().index(5, i).data()))
            self.tableView.setIndexWidget(comb_bgrjwu_bgrofj1_table_site, comb_bgrjwu_bgrofj1_table)
            i = i + 1

        self.tableView.model().setHeaderData(4, Qt.Vertical, QColor("gray"), Qt.BackgroundRole)  # Не работает

    def createToolBars(self):
        self.newAction = QAction("Новый\nобразец", self)
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.addAction(self.newAction)

    def bgrbom(self):
        v = self.tableView.model().columnCount()
        self.tableView.model().insertColumn(v)
        self.tableView.model().setData(self.tableView.model().index(4, v), QColor("gray"), Qt.BackgroundRole)
        comb_table = QComboBox()
        comb_table.wheelEvent = lambda event: None
        comb_table.addItems(["1", "2", "3", "4"])
        comb_table_site = self.tableView.model().index(5, v)
        self.tableView.setIndexWidget(comb_table_site, comb_table)

if __name__ == "__main__":
    import sys
    app1 = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app1.exec_()) 

Пробовал применять setHeaderData, но почитав некоторые ответы (https://stackoverflow.com/questions/32147213/how-to-change-the-background-color-from-the-headerhorizontal-vertical-qtable) понял, что в среде Windows эта функция именно для изменения цвета фона не работает.

Там же советуют переопределить класс QHeaderView. Но я не понимаю, как это делается.
Кто-нибудь может помочь?

Ответы

▲ 1Принят

Не уверен, что правильно понимаю, то что вы хотите сделать.

Попробуйте так:

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QColor
from PyQt5.QtWidgets import QApplication, QHeaderView, QTableView, \
    QMainWindow,  QAction, QComboBox, QTabWidget, QLabel


class FreezeTableWidget(QTableView):
    def __init__(self, model):
        super().__init__()
        self.setModel(model)
        self.frozenTableView = QTableView(self)
        self.init()
        self.frozenTableView.horizontalScrollBar().valueChanged.connect(
            self.horizontalScrollBar().setValue)
        self.horizontalScrollBar().valueChanged.connect(
            self.frozenTableView.horizontalScrollBar().setValue)
    def init(self):
        self.frozenTableView.setModel(self.model())
        self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
        self.frozenTableView.setFocusPolicy(Qt.NoFocus)
        self.frozenTableView.horizontalHeader().hide()

# +++ vvv         
        self.frozenTableView.verticalHeader().setStyleSheet('''
QHeaderView, QHeaderView::section {                              /* <---- */ 
                border: 2px solid;
                selection-background-color: #3399FF;
                font: Bold;
                font-size: 20px;
                font-family: Times New Roman;
color: #ff0;                                                     /* <---- */ 
background-color: #05595B;                                       /* <---- */ 
} 
           ''')
# +++ ^^^
        
        self.frozenTableView.verticalHeader().verticalOffset()
        self.frozenTableView.verticalHeader().setFixedWidth(150)
        self.frozenTableView.verticalHeader().setSectionResizeMode(
            QHeaderView.Fixed)
        self.viewport().stackUnder(self.frozenTableView)
        self.frozenTableView.setStyleSheet('''
            QTableView { border: none;
                         background-color: white;
                         selection-background-color: #3399FF;
                         font: Bold;
                         text-align: center;
            }
        ''')
        self.frozenTableView.setSelectionModel(self.selectionModel())
        for row1 in range(4, self.model().rowCount()):
            self.frozenTableView.setRowHidden(row1, True)
        self.frozenTableView.setColumnWidth(0, self.columnWidth(0))
        self.frozenTableView.setHorizontalScrollBarPolicy(1)
        self.frozenTableView.setVerticalScrollBarPolicy(1)
        self.frozenTableView.show()
        self.updateFrozenTableGeometry()
        self.setHorizontalScrollMode(self.ScrollPerPixel)
        self.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setHorizontalScrollMode(self.ScrollPerPixel)
        
    def updateSectionWidth(self, logicalIndex, newSize):
        self.frozenTableView.setColumnWidth(logicalIndex, newSize)
        
    def resizeEvent(self, event):
        super(FreezeTableWidget, self).resizeEvent(event)
        self.updateFrozenTableGeometry()
        
    def updateFrozenTableGeometry(self):
        self.frozenTableView.setGeometry(
            self.frameWidth(),
            self.horizontalHeader().height(),
            self.viewport().width() + 150,
            4 * self.rowHeight(0))

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.createToolBars()
        model = QStandardItemModel()
        header = ["Ввод1", "Ввод2", "Ввод3", "Ввод4", "Ввод5", 
                  "Ввод6", "Ввод7", "Ввод8", "Ввод9"]
        model.setVerticalHeaderLabels(header)
        widht_mon = 700
        height_mon = 500

        self.tableView = FreezeTableWidget(model)
        self.tableView.verticalHeader().setFixedWidth(150)
        self.tableView.horizontalHeader().hide()
        self.tabwidget2 = QTabWidget()
        self.setCentralWidget(self.tabwidget2)
        self.tabwidget2.insertTab(0, self.tableView, "ВВОД ДАННЫХ")
        self.resize(widht_mon, height_mon)

# +++ vvv       
        self.tableView.verticalHeader().setStyleSheet('''
QHeaderView, QHeaderView::section {                              /* <---- */ 
                border: 2px solid;
                selection-background-color: #3399FF;
                font: Bold;
                font-size: 20px;
                font-family: Times New Roman;
color: #ff0;                                                     /* <---- */ 
background-color: #05595B;                                       /* <---- */
           }
        ''')
# +++ ^^^
                
        self.newAction.triggered.connect(self.bgrbom)
        column_count1 = model.columnCount()
        i = 0
        while i < column_count1:
            comb_bgrjwu_bgrofj1_table = QComboBox()
            comb_bgrjwu_bgrofj1_table.wheelEvent = lambda event: None
            comb_bgrjwu_bgrofj1_table.addItems(["1", "2", "3"])
            comb_bgrjwu_bgrofj1_table_site = self.tableView.model().index(5, i)
            comb_bgrjwu_bgrofj1_table.setCurrentIndex(
                int(self.tableView.model().index(5, i).data()))
            self.tableView.setIndexWidget(
                comb_bgrjwu_bgrofj1_table_site, comb_bgrjwu_bgrofj1_table)
            i = i + 1

        self.tableView.model().setHeaderData(
            4, 
            Qt.Vertical, 
            QColor("gray"), 
            Qt.BackgroundRole)                              # Не работает

    def createToolBars(self):
        self.newAction = QAction("Новый\nобразец", self)
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.addAction(self.newAction)

    def bgrbom(self):
        v = self.tableView.model().columnCount()
        self.tableView.model().insertColumn(v)
        self.tableView.model().setData(
            self.tableView.model().index(4, v), QColor("gray"), Qt.BackgroundRole)
        comb_table = QComboBox()
        comb_table.wheelEvent = lambda event: None
        comb_table.addItems(["1", "2", "3", "4"])
        comb_table_site = self.tableView.model().index(5, v)
        self.tableView.setIndexWidget(comb_table_site, comb_table)


if __name__ == "__main__":
    import sys
    app1 = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app1.exec_()) 

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



UPDATE:

Дело в том, что мне нужно изменить цвет в 1 ячейке заголовка, а не во всем заголовке.

Попробуйте так:

from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QStandardItemModel, QColor, QPen, QFont, \
    QFontMetrics, QBrush
from PyQt5.QtWidgets import QApplication, QHeaderView, QTableView, \
    QMainWindow,  QAction, QComboBox, QTabWidget, QLabel


class HeaderView(QHeaderView):                                   # !!! +++
    def __init__(self, parent=None):
        super().__init__(Qt.Orientation.Vertical, parent)
        self._font = QFont("Times", 12, QFont.Weight.Bold)
        self.setFixedWidth(150)     
    
    def paintSection(self, painter, rect, index):                # !!! +++
        data = self._get_data(index)
        painter.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
        painter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
        painter.setFont(self._font)
        painter.drawRect(rect.x(), rect.y(), rect.width()+.1, rect.height()+1.2)      

        if index == 1:        
            painter.drawText(QPointF(rect.x()+5, rect.y()+20), data)
        else:
            super().paintSection(painter, rect, index)   

    def _get_data(self, index):
        return self.model().headerData(index, self.orientation())


class FreezeTableWidget(QTableView):
    def __init__(self, model):
        super().__init__()
        self.setModel(model)
        self.frozenTableView = QTableView(self)
        self.init()
        self.frozenTableView.horizontalScrollBar().valueChanged.connect(
            self.horizontalScrollBar().setValue)
        self.horizontalScrollBar().valueChanged.connect(
            self.frozenTableView.horizontalScrollBar().setValue)
 
        header = HeaderView(self.frozenTableView)
        self.frozenTableView.setVerticalHeader(header)
            
    def init(self):
        self.frozenTableView.setModel(self.model())
        self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
        self.frozenTableView.setFocusPolicy(Qt.NoFocus)
        self.frozenTableView.horizontalHeader().hide()
        
        self.frozenTableView.verticalHeader().setStyleSheet('''
QHeaderView, QHeaderView::section {                             
                border: 2px solid;
                selection-background-color: #3399FF;
                font: Bold;
                font-size: 20px;
                font-family: Times New Roman;
color: #ff0;                                                    
background-color: #05595B;                                      
} 
           ''')
        
        self.frozenTableView.verticalHeader().verticalOffset()
        self.frozenTableView.verticalHeader().setFixedWidth(150)
        self.frozenTableView.verticalHeader().setSectionResizeMode(
            QHeaderView.Fixed)
        self.viewport().stackUnder(self.frozenTableView)
        self.frozenTableView.setStyleSheet('''
            QTableView { border: none;
                         background-color: white;
                         selection-background-color: #3399FF;
                         font: Bold;
                         text-align: center;
            }
        ''')
        self.frozenTableView.setSelectionModel(self.selectionModel())
        for row1 in range(4, self.model().rowCount()):
            self.frozenTableView.setRowHidden(row1, True)
        self.frozenTableView.setColumnWidth(0, self.columnWidth(0))
        self.frozenTableView.setHorizontalScrollBarPolicy(1)
        self.frozenTableView.setVerticalScrollBarPolicy(1)
        self.frozenTableView.show()
        self.updateFrozenTableGeometry()
        self.setHorizontalScrollMode(self.ScrollPerPixel)
        self.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel)
        self.frozenTableView.setHorizontalScrollMode(self.ScrollPerPixel)
        
    def updateSectionWidth(self, logicalIndex, newSize):
        self.frozenTableView.setColumnWidth(logicalIndex, newSize)
        
    def resizeEvent(self, event):
        super(FreezeTableWidget, self).resizeEvent(event)
        self.updateFrozenTableGeometry()
        
    def updateFrozenTableGeometry(self):
        self.frozenTableView.setGeometry(
            self.frameWidth(),
            self.horizontalHeader().height(),
            self.viewport().width() + 150,
            4 * self.rowHeight(0))

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.createToolBars()
        model = QStandardItemModel()
        header = ["Ввод1", "Ввод2", "Ввод3", "Ввод4", "Ввод5", 
                  "Ввод6", "Ввод7", "Ввод8", "Ввод9"]
        model.setVerticalHeaderLabels(header)
        widht_mon = 700
        height_mon = 500

        self.tableView = FreezeTableWidget(model)
        self.tableView.verticalHeader().setFixedWidth(150)
        self.tableView.horizontalHeader().hide()
        self.tabwidget2 = QTabWidget()
        self.setCentralWidget(self.tabwidget2)
        self.tabwidget2.insertTab(0, self.tableView, "ВВОД ДАННЫХ")
        self.resize(widht_mon, height_mon)
      
        self.tableView.verticalHeader().setStyleSheet('''
QHeaderView, QHeaderView::section {                              /* <---- */ 
                border: 2px solid;
                selection-background-color: #3399FF;
                font: Bold;
                font-size: 20px;
                font-family: Times New Roman;
color: #ff0;                                                     /* <---- */ 
background-color: #05595B;                                       /* <---- */
           }
        ''')
                
        self.newAction.triggered.connect(self.bgrbom)
        column_count1 = model.columnCount()
        i = 0
        while i < column_count1:
            comb_bgrjwu_bgrofj1_table = QComboBox()
            comb_bgrjwu_bgrofj1_table.wheelEvent = lambda event: None
            comb_bgrjwu_bgrofj1_table.addItems(["1", "2", "3"])
            comb_bgrjwu_bgrofj1_table_site = self.tableView.model().index(5, i)
            comb_bgrjwu_bgrofj1_table.setCurrentIndex(
                int(self.tableView.model().index(5, i).data()))
            self.tableView.setIndexWidget(
                comb_bgrjwu_bgrofj1_table_site, comb_bgrjwu_bgrofj1_table)
            i = i + 1

        self.tableView.model().setHeaderData(
            4, 
            Qt.Vertical, 
            QColor("gray"), 
            Qt.BackgroundRole)                              # Не работает

    def createToolBars(self):
        self.newAction = QAction("Новый\nобразец", self)
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.addAction(self.newAction)

    def bgrbom(self):
        v = self.tableView.model().columnCount()
        self.tableView.model().insertColumn(v)
        self.tableView.model().setData(
            self.tableView.model().index(4, v), QColor("gray"), Qt.BackgroundRole)
        comb_table = QComboBox()
        comb_table.wheelEvent = lambda event: None
        comb_table.addItems(["1", "2", "3", "4"])
        comb_table_site = self.tableView.model().index(5, v)
        self.tableView.setIndexWidget(comb_table_site, comb_table)


if __name__ == "__main__":
    import sys
    app1 = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app1.exec_()) 

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