具有扩展属性的深色主题
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 元素的属性动态更改颜色。
虽然我每次都可以从头开始重建整个列表,但我怀疑没有更好的方法。
我的环境
- Archlinux x64 内核 5.10.5
- 桌面环境:Xfce4
- Window 管理器:Xfwm4
- Python版本:3.9.1
- Pyqt5 版本:5.15.2
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()
目标
同时构建一个基于 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 元素的属性动态更改颜色。
虽然我每次都可以从头开始重建整个列表,但我怀疑没有更好的方法。
我的环境
- Archlinux x64 内核 5.10.5
- 桌面环境:Xfce4
- Window 管理器:Xfwm4
- Python版本:3.9.1
- Pyqt5 版本:5.15.2
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()