在PyQt中为QTableWidget的每个水平标题设置不同的颜色。

6
我可以帮助你翻译以下内容,这是关于 IT 技术的:我有一个 QTableWidget 表格,我想根据一些条件为每个水平表头项目设置不同的颜色。目前,我的解决方案如下:
stylesheet = "::section{Background-color:rgb(190,1,1)}"
self.ui.Table.horizontalHeader().setStyleSheet(stylesheet)

这种方法可以实现效果,但是它会将所有标题同时着色,而我无法更改单个标题的颜色。因此,下一步的逻辑应该是:

self.ui.Table.horizontalHeaderItem(0).setStyleSheet(stylesheet) 

这个方法不可行,因为一个头部项目不支持设置样式表。

最后:

self.ui.Table.horizontalHeaderItem(0).setBackgroundColor(QtCore.Qt.red)

这段代码在没有引发Python错误的情况下运行良好,但似乎对背景颜色没有任何影响。
我已经查看了这个答案,它是我第一次尝试的火花。然而,它只处理所有标题都用相同的颜色着色的情况。
如何为每个标题单独着色?
3个回答

4

您可以通过使用以下配方来实现:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class MyFrame(QtWidgets.QFrame):
    def __init__(self, parent=None,initials=None):
        QtWidgets.QFrame.__init__(self, parent)
        self.table = QtWidgets.QTableWidget(5,3,self)
        self.table.move(30,30)
        self.table.resize(400,300)

        item1 = QtWidgets.QTableWidgetItem('red')
        item1.setBackground(QtGui.QColor(255, 0, 0))
        self.table.setHorizontalHeaderItem(0,item1)

        item2 = QtWidgets.QTableWidgetItem('green')
        item2.setBackground(QtGui.QColor(0, 255, 0))
        self.table.setHorizontalHeaderItem(1,item2)

        item3 = QtWidgets.QTableWidgetItem('blue')
        item3.setBackground(QtGui.QColor(0, 0, 255))
        self.table.setHorizontalHeaderItem(2,item3)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle(QtWidgets.QStyleFactory.create('Fusion')) # won't work on windows style.
    Frame = MyFrame(None)
    Frame.resize(500,400)
    Frame.show()
    app.exec_()

将代码修改成这样:

在QTableWidget中为标题项设置不同的颜色

需要考虑的一件事是,Windows风格不允许您这样做。这就是我不得不将风格更改为Fusion的原因。


很不幸,我被迫使用PyQt4。在我调整了所有的导入后,我得到了一个没有颜色的表头的表格。我猜这个特性似乎在PyQt4中无法工作。如果有人能提供PyQt4的解决方案,我会等待一段时间。否则,对于任何在PyQt5上遇到困难的用户,我将把你的答案标记为已接受的答案。 - stebu92
你确定吗?在排除导入语句的情况下,所有内容(涉及此示例)应该都能以相同的方式工作。你改变了应用程序的样式吗?“app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))”尝试使用其他样式,因为我不知道Qt版本之间权限是否发生了变化。对于“Windows”样式,我相当肯定它不起作用,无论Qt版本如何。 - armatita
你是对的,它可以在Plastique和Cleanlooks中工作,但不能在Fusion或Windows中工作。 - stebu92
你好,是否可以仅更改左侧的计数器列?(1、2、3、4...) - KiDo

2
“在标题中使用setBackground似乎没有效果”
看这里:https://forum.qt.io/topic/74609/cannot-set-the-backgroud-color-of-the-horizontalheaderitem-of-qtablewidget/2 我写了这个小应用程序;字体类型和大小以及前景色都会生效。
from PyQt4 import QtGui
from PyQt4.QtGui import QFont

app = QtGui.QApplication([])

columns = ['Column 0', 'Column 1', 'Column 2']
items = [['Row%s Col%s' % (row, col) for col in range(len(columns))] for row in range(1)]

view = QtGui.QTableWidget()

view.setColumnCount(len(columns))
view.setHorizontalHeaderLabels(columns)
view.setRowCount(len(items))
for row, item in enumerate(items):
    for col, column_name in enumerate(item):
        item = QtGui.QTableWidgetItem("%s" % column_name)
        view.setItem(row, col, item)
    view.setRowHeight(row, 16)

fnt = QFont()
fnt.setPointSize(15)
fnt.setBold(True)
fnt.setFamily("Arial")

item1 = view.horizontalHeaderItem(0)
item1.setForeground(QtGui.QColor(255, 0, 0))
item1.setBackground(QtGui.QColor(0, 0, 0))  # Black background! does not work!!
item1.setFont(fnt)

item2 = view.horizontalHeaderItem(1)
item2.setForeground(QtGui.QColor(0, 255, 0))
item2.setFont(fnt)

item3 = view.horizontalHeaderItem(2)
item3.setForeground(QtGui.QColor(255, 0, 255))

view.setHorizontalHeaderItem(0, item1)
view.setHorizontalHeaderItem(1, item2)
view.setHorizontalHeaderItem(2, item3)
view.show()
app.exec_()

enter image description here


2
app = QApplication([])后添加app.setStyle(QStyleFactory.create('Fusion')),就可以开始使用setBackground了。 - S. Nick

1
这是对armatita的回答进行修改,与默认的Windows样式配合使用。
import sys
from PySide6 import QtGui, QtWidgets


class ColoredTableHeaderStyle(QtWidgets.QProxyStyle):
    def drawControl(self, element, option, painter, widget=None):
        if element == QtWidgets.QStyle.ControlElement.CE_HeaderSection and isinstance(widget, QtWidgets.QHeaderView):
            fill = option.palette.brush(QtGui.QPalette.ColorRole.Window)  # the Qt implementation actually sets the background brush on the Window color role, the default Windows style simply ignores it
            painter.fillRect(option.rect, fill)  # fill the header section with the background brush
        else:
            self.baseStyle().drawControl(element, option, painter, widget)  # use the default implementation in all other cases


class MyFrame(QtWidgets.QFrame):
    def __init__(self, parent=None):
        QtWidgets.QFrame.__init__(self, parent)
        self.table = QtWidgets.QTableWidget(5, 3, self)
        self.table.move(30, 30)
        self.table.resize(400, 300)

        item1 = QtWidgets.QTableWidgetItem('red')
        item1.setBackground(QtGui.QColor(255, 0, 0))
        self.table.setHorizontalHeaderItem(0, item1)

        item2 = QtWidgets.QTableWidgetItem('green')
        item2.setBackground(QtGui.QColor(0, 255, 0))
        self.table.setHorizontalHeaderItem(1, item2)

        item3 = QtWidgets.QTableWidgetItem('blue')
        item3.setBackground(QtGui.QColor(0, 0, 255))
        self.table.setHorizontalHeaderItem(2, item3)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle(ColoredTableHeaderStyle(app.style()))  # use the proxy style reimplementing the drawing of table headers, otherwise identical with the default Windows style
    Frame = MyFrame(None)
    Frame.resize(500, 400)
    Frame.show()
    app.exec_()

可以通过使用自定义的QHeaderView子类来对水平标题进行着色来进行优化。这也适用于QTableView

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接