【问题标题】:Using FBS's get resource method in qss definitions?在 qss 定义中使用 FBS 的获取资源方法?
【发布时间】:2023-03-16 04:15:01
【问题描述】:

我有一个单独的 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 的一部分。 this answer 使用 python 字符串格式,但由于我有一些 rgba 颜色值也有 %,所以我不断收到关键错误。

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

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

【问题讨论】:

  • @eyllanesc 我认为我的问题有点直截了当,但我确定我添加了一个 MRE。
  • 有些东西没有定义,比如fileImporter是什么,图标在哪里等
  • 抱歉,我的文件导入器是一个扩展,用于获取具有一些附加条件的资源。对于图像文件,您现在可以使用任何东西。我只关心文件加载是否正确,同时保持 qss 结构
  • 扑通,你必须使用pyrcc5:pyrcc5 your.qrc -o your_rc.py

标签: python pyqt5 fbs


【解决方案1】:

使用 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())

更新:

分析the source code

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

【讨论】:

  • getattr 不起作用,我不得不更改一些东西 "tabBarPlus::closeButton.backgroundImage": f"url({app.get_resource('ui/close.png')})",property = key.split(".") qss[property[0]][property[1]].setValue(value) 但是,我的自定义类(例如 customView)变成了自定义视图,导致 qt 无法理解样式表(不能解析应用程序样式表)
  • @Blaine 告诉我您的示例不是 MRE,请提供,然后我会尽力帮助您
  • 我已经用更新的 MRE 更新了我的原始问题,复制了我当前的问题。根据 qstylesheet 源代码,我看到只打算修改蛇案例,但我不确定。我在示例中所做的所有更改是我将 QTabBar 更改为 customTabBar,遵循我在代码中的命名约定。解析后变成custom-tab-bar
  • @Blaine 我认为你发现了一个错误,我正在分析修复它的原因,但直到现在我发现如果课程以 Qt 开头,问题不会发生,你能改变你的课程吗到 QCustomTabBar?
  • 啊,我不介意改变一个类,但前提是你总是需要子类化 qt 类,我必须为我拥有的每个类更改类名。我认为对于一种解决方法,我将研究由 to string 返回的字符串的正则表达式替换
【解决方案2】:

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

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

shell 命令,

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-08-13
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多