为 QListWidget 中的特定项目设置不同的颜色
Posted
技术标签:
【中文标题】为 QListWidget 中的特定项目设置不同的颜色【英文标题】:Set different color to specifc items in QListWidget 【发布时间】:2022-01-19 00:21:13 【问题描述】:我有一个QListWidget
,我想为列表的每个项目添加边框底部并为项目设置背景颜色,我想为特定项目设置不同的背景颜色。
所以我使用了my_list.setStyleSheet("QListWidget::item border-bottom: 1px solid red; background-color: blue;")
并将背景颜色设置为我使用的特定项目item.setBackground(QtGui.QColor("#E3E3E3"))
问题是我设置不同颜色的特定项目没有得到这个颜色。
【问题讨论】:
您是否遇到任何错误? 不,我没有收到错误。 好的,给我一分钟 - 我会尝试重现。我以前做过这个工作,所以它是可能的。 已更新——问题不是我想的那样。我认为要做到这一点,您将需要列表中的自定义委托/小部件。 【参考方案1】:您不能在小部件上使用样式表和样式设置的组合——样式表将覆盖单个项目的任何设置。例如,以下代码在每个项目上使用setBackground
来更改背景颜色。
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
colors = [ '#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666']
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
w = QListWidget()
for n in range(8):
i = QListWidgetItem('%s' % n)
i.setBackground( QColor(colors[n]) )
w.addItem(i)
self.setCentralWidget(w)
self.show()
app = QApplication([])
w = MainWindow()
app.exec_()
结果输出:
但是,如果我们在结果中添加样式表行(第二个只有底部边框):
很遗憾,无法设置项目的边框和颜色。但是,您可以做的就是插入一个自定义小部件作为列表项,或者use an item delegate 来绘制该项目。这使您可以完全控制外观,但是您必须自己处理绘图。下面是使用自定义委托执行此操作的示例:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
colors = [ '#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666']
class MyDelegate(QItemDelegate):
def __init__(self, parent=None, *args):
QItemDelegate.__init__(self, parent, *args)
def paint(self, painter, option, index):
painter.save()
# set background color
painter.setPen(QPen(Qt.NoPen))
if option.state & QStyle.State_Selected:
# If the item is selected, always draw background red
painter.setBrush(QBrush(Qt.red))
else:
c = index.data(Qt.DisplayRole+1) # Get the color
painter.setBrush(QBrush(QColor(c)))
# Draw the background rectangle
painter.drawRect(option.rect)
# Draw the bottom border
# option.rect is the shape of the item; top left bottom right
# e.g. 0, 0, 256, 16 in the parent listwidget
painter.setPen(QPen(Qt.red))
painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
# Draw the text
painter.setPen(QPen(Qt.black))
text = index.data(Qt.DisplayRole)
# Adjust the rect (to pad)
option.rect.setLeft(5)
option.rect.setRight(option.rect.right()-5)
painter.drawText(option.rect, Qt.AlignLeft, text)
painter.restore()
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
de = MyDelegate(self)
w = QListWidget()
w.setItemDelegate(de)
for n in range(8):
s = '%s' % n
i = QListWidgetItem()
i.setData(Qt.DisplayRole, s) # The label
i.setData(Qt.DisplayRole+1, colors[n]) # The color
w.addItem(i)
self.setCentralWidget(w)
self.show()
app = QApplication([])
w = MainWindow()
app.exec_()
它给出以下输出:
使用委托的方法是定义一个paint
方法,该方法接受一个QPainter
对象(您可以使用它进行实际绘图),一个包含项目矩形的option
参数(相对于父窗口小部件) ) 和一个index
,您可以通过它检索项目数据。然后您使用QPainter 上的方法来绘制您的项目。
在上面的示例中,我们使用它来传递项目标签(位置Qt.DisplayRole
)和十六进制颜色(位置Qt.DisplayRole+1
)。 ItemDisplayRole 的名称文档列出了其他已定义的数据“角色”,但在大多数情况下,您可以忽略这些。
【讨论】:
@OussamaHe 看起来答案已被扩展。 请您帮我使用项目委托来绘制项目,因为我之前访问过链接并且我尝试使用委托项目但我没有成功,提前谢谢您 @OussamaHe 使用QItemDelegate
的示例更新了答案
感谢委托示例,如果我想在项目中添加按钮,我该怎么做?
您可以使用QStyleButton
在painter 中绘制它,但您还需要处理单击按钮(QItemDelegate.editorEvent
)。我可以提供一个例子,但你能打开一个新问题吗?这与所提出的问题无关。以上是关于为 QListWidget 中的特定项目设置不同的颜色的主要内容,如果未能解决你的问题,请参考以下文章