QLinearGradient pyqt5 不适用于 QLabel

问题描述 投票:0回答:1

在 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 具有背景颜色渐变

我的渐变:

pyqt5 gradient linear-gradients qtstylesheets qlabel
1个回答
0
投票

正如 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__()
的父参数将更改应用程序的所有权,从而使其持久化。

© www.soinside.com 2019 - 2024. All rights reserved.