具有扩展属性的深色主题

Dark Theme with extended properties

目标

同时构建一个基于 pyqt5 的图形用户界面,其中包含 QListWidget 以及许多动态生成的 QListWidgetItem。一些 QListWidgetItem 具有颜色指示器,颜色指示器基于它们在单击时打开的内容的属性。

到目前为止,我只使用了默认的颜色主题,并在创建时对每个列表项使用了带有 .setBackground 的画笔,以获得我想要的配色方案。

现在我尝试添加一个新的深色主题,同时在创建对象后动态更改颜色。为此,我创建了一个新调色板并为应用程序设置了调色板。

预期和实际结果

为了处理列表项,我首先尝试设置 属性 如下:

item.setProperty('cool', True)

这返回了一个错误,指示 QListWidgetItem 没有 setProperty 属性,我认为原因是 QListWidgetItem 不继承 QObject

然后我尝试创建自己的 class 来设置 属性:

class ThemedQListWidgetItem(QListWidgetItem):
    def __init__(self, *args, **kwargs):
        QListWidgetItem.__init__(self, *args, **kwargs)
        self.cool = False

并使用以下方法设置颜色:

app.setPalette(darkPalette)
app.setStyleSheet("""
            ThemedQListWidgetItem[cool="true"] {
                background-color: red;}
            ThemedQListWidgetItem[cool="false"] {
                background-color: palette(base);}
        """)

应用了深色主题但没有显示红色项目,我没有收到任何错误。

也许我在 pyqt 的使用方式上做错了什么。必须有一种简单的方法可以根据 gui 元素的属性动态更改颜色。

虽然我每次都可以从头开始重建整个列表,但我怀疑没有更好的方法。

我的环境

QListWidgetItem 是QListWidget 显示的信息的表示,因此Qt StyleSheet 不能用于绘画,因为它们不是可视元素。 QListWidget 使用 QSS 绘制视觉项目(除了使用来自 QListWidgetItem 的信息)。所以如果你想要一个基于 属性 的绘画,那么你可以通过委托来完成:

import random
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import (
    QApplication,
    QListWidget,
    QListWidgetItem,
    QStyledItemDelegate,
)

CoolRole = Qt.UserRole


class Delegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        if index.data(CoolRole):
            option.backgroundBrush = QColor("red")


def main():
    app = QApplication(sys.argv)
    w = QListWidget()
    delegate = Delegate(w)
    w.setItemDelegate(delegate)
    for i in range(10):
        it = QListWidgetItem()
        it.setText(f"item {i}")
        cool = random.choice((True, False))
        it.setData(CoolRole, cool)
        w.addItem(it)
    w.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()