1

我有一个单独的 qss 样式表,其中包含我的整个应用程序的样式表定义。我需要添加一个关闭按钮作为背景图片,因为我找不到有关使用内置图标的文档。

customTabBar::close-button {
    padding: 0px;
    margin: 0px;
    border-radius: 2px;
    border-color: rgba(0, 0, 0, 50%);
    background-image: url(%(closeIcon)s);
    background-position: center center;
    background-repeat: none;
}

from fbs_runtime.application_context.PyQt5 import ApplicationContext

import qstylizer.parser


customIcons = {
    "customTabBar::closeButton.backgroundImage": f"url({app.get_resource('ui/close.png')})",
}

app = ApplicationContext()

with open(app.get_resource("app.qss"), "r") as stylesheet:
    css = qstylizer.parser.parse(stylesheet.read())
    for key, value in customIcons.items():
        property = key.split(".")
        css[property[0]][property[1]].setValue(value)
    app.app.setStyleSheet(css.toString())

文件存储在默认的 fbs 结构中,位于 src/main/resource/base/ui/*.png

因为我不能使用带有花括号的 fstrings 作为 qt 的一部分。这个答案使用 python 字符串格式,但由于我有一些 rgba 颜色值也有 % ,所以我不断收到关键错误。

由于我不能使用 %ages 或花括号,我正在考虑使用 get_resource 构建一个 qproperty,但我不确定如何。我需要我的 qss 交叉兼容并且无法逃脱我的花括号。

我的主要问题是,当我使用 FBS 冻结将应用程序与 fbs 打包时,图像将不可用

4

2 回答 2

2

使用 python 格式化工具解析和修改 Qt 样式表可能很复杂,例如在您尝试格式化(0, 0, 0, 50%)导致错误的情况下,因此我建议使用qstylizer( python -m pip install qstylizer),以便您可以轻松修改属性:

QTabBar::close-button {
    padding: 0px;
    margin: 0px;
    border-radius: 2px;
    border-color: rgba(0, 0, 0, 50%);
    background-position: center center;
    background-repeat: none;
}
import functools

from fbs_runtime.application_context.PyQt5 import ApplicationContext

import qstylizer.parser


customIcons = {
    "QTabBar.closeButton.backgroundImage": f"url({app.get_resource('ui/close.png')})",
}

app = ApplicationContext()

with open(app.get_resource("app.qss"), "r") as stylesheet:
    css = qstylizer.parser.parse(stylesheet.read())
    for key, value in customIcons.items():
        obj = functools.reduce(getattr, key.split("."), css)
        obj.setValue(value)
    app.app.setStyleSheet(css.toString())

更新:

分析源代码

if key and key[0] not in ["Q", "#", "[", " "] and not key.istitle():
    key = inflection.underscore(key)

似乎这些类是TitleCase所以一个可能的解决方案是将类的名称更改为Customtabbar

Customtabbar::close-button {
    padding: 0px;
    margin: 0px;
    border-radius: 2px;
    border-color: rgba(0, 0, 0, 50%);
    background-position: center center;
    background-repeat: none;
}
app = ApplicationContext()

customIcons = {
    "Customtabbar::close-button": {
        "background-image": f"url({app.get_resource('ui/close.png')})"
    },
}

with open(app.get_resource("app.qss"), "r") as stylesheet:
    css = qstylizer.parser.parse(stylesheet.read())
    for qcls, value in customIcons.items():
        for prop, v in value.items():
            css[qcls][prop] = v
    app.app.setStyleSheet(css.toString())

根据 PEP,类名必须是 CapWords,所以我通过更改创建了一个分支:

qstylizer/style.py

if key and key[0] not in ["Q", "#", "[", " "] and not key.istitle():

经过

if key and key[0] not in ["Q", "#", "[", " "] and key != inflection.camelize(key):

现在接受符合 PEP8 的类的名称。

CustomTabBar::close-button {
    padding: 0px;
    margin: 0px;
    border-radius: 2px;
    border-color: rgba(0, 0, 0, 50%);
    background-position: center center;
    background-repeat: none;
}
app = ApplicationContext()

customIcons = {
    "CustomTabBar::close-button": {
        "background-image": f"url({app.get_resource('ui/close.png')})"
    },
}

with open(app.get_resource("app.qss"), "r") as stylesheet:
    css = qstylizer.parser.parse(stylesheet.read())
    for qcls, value in customIcons.items():
        for prop, v in value.items():
            css[qcls][prop] = v
    app.app.setStyleSheet(css.toString())

更新2:

PR已被接受,因此只需要更新库:python -m pip install qstylizer --upgrade.

于 2020-06-18T17:17:20.760 回答
0

根据@eyllanesc 的建议,这是我的解决方案。rcc 文件,

<RCC>
  <qresource>
    <file alias="closeIcon">close.png</file>
  </qresource>
</RCC>

外壳命令,

pyrcc5 -o resources.py resources.rcc

这是样式表。

TabBarPlus::close-button {
    background-image: url(:/closeIcon);
    padding: 0px;
    margin: 0px;
    border-radius: 2px;
    background-position: center center;
    background-repeat: none;
}
于 2020-07-07T01:51:19.870 回答