在 qt 设计器中创建 QLabel 并设置样式表:
font: bold 50px;
color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(13, 115, 119, 255), stop:1 rgba(78, 204, 163, 255));
我希望在样式表中描述渐变。 只有文本颜色或字体颜色,我不想让 QLabel 具有背景颜色渐变
正如 alec 在评论中指出的那样,这是一个已知但仍未解决的错误。
它似乎只影响某些样式:我不能用 Oxygen 和 Breeze 重现它,但我可以用 Fusion 和 Windows,这可能意味着它是由
QStyle.drawItemText()
的默认实现和 QStyleSheetStyle 提供参数的方式引起的该功能(特别是调色板)。
我最终会对此进行更多检查,但现在看来可能的解决方法是在样式表影响标签时重置标签调色板(通过使用父级或应用程序)。
请注意,这在概念上是一个 bad 解决方法,更像是一种“蛮力”解决方法;请记住,正如文档警告,我们不应将
setPalette()
与样式表一起使用。
仍然,考虑到 QLabel 的部分简单性,我们可以否决该方面,只要它有效(并且该错误最终得到修复)。
changeEvent()
并检查PaletteChange
变化,然后根据父类或整个应用程序重置调色板。请注意,由于我们正在改变 again 调色板,我们需要进行基本检查以避免递归:
class FixLabel(QLabel):
_recursiveCheck = False
def changeEvent(self, event):
super().changeEvent(event)
if event.type() == event.PaletteChange and not self._recursiveCheck:
self._recursiveCheck = True
self.setPalette(
(self.parent() or QApplication.instance()).palette())
self._recursiveCheck = False
这显然可以为 Designer 使用提升的小部件或通过为 QApplication 安装事件过滤器来完成。
在那种情况下,我们最终可以检查
WA_StyleSheetTarget
属性,它告诉我们标签是否实际使用样式表:
class FixLabelFilter(QObject):
def __init__(self):
app = QApplication.instance()
super().__init__(app)
self.recursiveSet = set()
app.installEventFilter(self)
def eventFilter(self, obj, event):
if (
isinstance(obj, QLabel)
and event.type() == event.PaletteChange
and obj not in self.recursiveSet
and obj.testAttribute(Qt.WA_StyleSheetTarget)
):
self.recursiveSet.add(obj)
obj.setPalette(
(self.parent() or QApplication.instance()).palette()
)
self.recursiveSet.remove(obj)
return super().eventFilter(obj, event)
...
app = QApplication(sys.argv)
FixLabelFilter()
...
请注意,无需为
FixLabelFilter
实例创建引用,因为 super().__init__()
的父参数将更改应用程序的所有权,从而使其持久化。