【PyQt学习篇 · ⑮】:qrc/rcc资源系统

qrc使用介绍

在PyQt中,qrc文件是一种资源文件,用于将应用程序所需的资源(如图像、音频文件、样式表等)打包到一个单独的二进制文件中,以便在运行时轻松地加载和访问这些资源。

qrc文件是用XML格式编写的,其中包含资源的路径和名称。PyQt提供了一个工具(pyrcc5),用于将qrc文件编译成Python代码,这些代码包含在应用程序中使用这些资源的必要逻辑。

示例
项目文件结构

$ tree Resources
Resources
├── photo
│   ├── PyQt.png
│   └── Struct.png
├── GIF
│   └── Thanks.gif
└── resources.qrc

以下是一个简单的resources.qrc示例:

<!DOCTYPE RCC>
<RCC>
    <qresource>
        <file>photo/PyQt.png</file>
        <file>photo/Struct.png</file>
    </qresource>
    <qresource>
        <file>GIF/Thanks.gif</file>
    </qresource>
</RCC>

在这个例子中,qrc文件指定了三个资源:PyQt.png、Struct.png、Thanks.gif,前两个位于photo文件夹中,最后一个位于GIF文件夹中。

rcc编译资源

rcc(Resource Compiler)是一个用于将资源文件编译成二进制格式的工具,它通常与Qt框架一起使用。在PyQt中,rcc工具用于编译qrc文件,将其中定义的资源打包成一个二进制文件,这样在运行时就可以方便地加载和使用这些资源,而不需要原始的资源文件。

rcc 的安装与基本使用

当通过pip安装PyQt或其他PySide时,会同时自动安装对应版本的 rcc 工具。这些工具的调用命令有所不同(详见下表),但使用方式与功能是一致的。激活已安装 PyQt 的 Python 虚拟环境,在命令行(注意不是 Python 交互式解释器)中输入对应的 rcc 命令即可。

平台rcc命令名称
PySide6pyside6-rcc
PySide2pyside2-rcc
PyQt6不提供
PyQt5pyrcc-5

注意:使用 PySide6 提供的 pyside6-rcc 工具编译出的 .py 文件,也可以放入 PyQt6 项目中使用,只需将文件开头的 from PySide6 import QtCore 替换为 from PyQt6 import QtCore 即可。

  • 例如,对于PyQt5,在命令行中使用cd命令,切换到当前项目文件夹下——Resources
    在这里插入图片描述

  • 然后,输入以下命令:

pyrcc5 -o compiled_resources.py resources.qrc

即可将 resources.qrc 中列出的资源文件编译到输出文件 compiled_resources.py 中。

编译成Python文件

运行成功后,在 .qrc 中声明的所有资源文件都已经被编译到 compiled_resources.py

以下是compiled_resources.py的内容:

# -*- coding: utf-8 -*-

# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2)
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore

qt_resource_data = b"......"

qt_resource_name = b"......"

qt_resource_struct_v1 = b"......"

qt_resource_struct_v2 = b"......"

qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
    rcc_version = 1
    qt_resource_struct = qt_resource_struct_v1
else:
    rcc_version = 2
    qt_resource_struct = qt_resource_struct_v2

def qInitResources():
    QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)

def qCleanupResources():
    QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)

qInitResources()

最上方的注释标明了该文件由与 Qt v5.15.2 版本匹配的资源编译器生成。并警告用户不要直接编辑该文件,因为所有修改都会被下一次编译操作覆盖掉。

qt_resource_dataqt_resource_nameqt_resource_struct_v1qt_resource_struct_v2中是二进制编码字符串,因为字符串过长,以上用省略号(……)代替。

其中:

  • qt_resource_data - 资源文件内容数据
  • qt_resource_name - 资源文件名称
  • qt_resource_struct - 资源结构

函数 qInitResources()qCleanupResources(),分别对应向 Qt 中注册资源与清理资源。

代码的最后一行调用了注册资源函数。

使用资源系统文件

方式一:导入资源系统文件

资源系统文件——compiled_resources.py已生成,以下是使用案例。

创建一个demo.py文件,在demo.py文件中导入资源系统文件进行使用:

# 以下是demo.py文件内容

from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap, QMovie
import sys
import compiled_resources

class Demo(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setup_ui()

    def setup_ui(self):
        self.widget = QWidget()
        self.setCentralWidget(self.widget)

        vbox = QVBoxLayout(self.widget)

        label1 = QLabel()
        label1.setPixmap(QPixmap(':/photo/PyQt.png').scaled(50, 50))

        label2 = QLabel()
        label2.setPixmap(QPixmap(':/photo/Struct.png').scaled(50, 50))
        # 或
        # label2.setStyleSheet('background-image: url(:/photo/Struct.png); background-size: 50px 50x; background-repeat: no-repeat;')

        movie = QMovie(':/GIF/Thanks.gif')
        label3 = QLabel()
        label3.setMovie(movie)
        movie.start()

        vbox.addWidget(label1)
        vbox.addWidget(label2)
        vbox.addWidget(label3)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    d = Demo()
    d.show()
    sys.exit(app.exec_())

运行结果:
在这里插入图片描述

方式二:整合资源系统文件

compiled_resources.py文件中的内容,写入到demo.py文件中。

例:

# 以下是demo.py文件内容

from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap, QMovie
import sys
import compiled_resources

class Demo(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setup_ui()

    def setup_ui(self):
        self.widget = QWidget()
        self.setCentralWidget(self.widget)

        vbox = QVBoxLayout(self.widget)

        label1 = QLabel()
        label1.setPixmap(QPixmap(':/photo/PyQt.png').scaled(50, 50))

        label2 = QLabel()
        label2.setPixmap(QPixmap(':/photo/Struct.png').scaled(50, 50))
        # 或
        # label2.setStyleSheet('background-image: url(:/photo/Struct.png); background-size: 50px 50x; background-repeat: no-repeat;')

        movie = QMovie(':/GIF/Thanks.gif')
        label3 = QLabel()
        label3.setMovie(movie)
        movie.start()

        vbox.addWidget(label1)
        vbox.addWidget(label2)
        vbox.addWidget(label3)

from PyQt5 import QtCore

qt_resource_data = b"......"

qt_resource_name = b"......"

qt_resource_struct_v1 = b"......"

qt_resource_struct_v2 = b"......"

qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
    rcc_version = 1
    qt_resource_struct = qt_resource_struct_v1
else:
    rcc_version = 2
    qt_resource_struct = qt_resource_struct_v2

def qInitResources():
    QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)

def qCleanupResources():
    QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)

qInitResources()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    d = Demo()
    d.show()
    sys.exit(app.exec_())

运行结果:
在这里插入图片描述

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值