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

文章目录

qrc使用介绍

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

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

示例

项目文件结构

python 复制代码
$ tree Resources
Resources
├── photo
│   ├── PyQt.png
│   └── Struct.png
├── GIF
│   └── Thanks.gif
└── resources.qrc

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

python 复制代码
<!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命令名称
PySide6 pyside6-rcc
PySide2 pyside2-rcc
PyQt6 不提供
PyQt5 pyrcc-5

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

  • 例如,对于PyQt5,在命令行中使用cd命令,切换到当前项目文件夹下------Resources

  • 然后,输入以下命令:

python 复制代码
pyrcc5 -o compiled_resources.py resources.qrc

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

编译成Python文件

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

以下是compiled_resources.py的内容:

python 复制代码
# -*- 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文件中导入资源系统文件进行使用:

python 复制代码
# 以下是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文件中。

例:

python 复制代码
# 以下是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_())

运行结果:

相关推荐
charlie11451419114 分钟前
从零开始理解 CSS:让网页“活”起来的语言2
前端·css·笔记·学习·选择器·样式表·原生
im_AMBER14 分钟前
Leetcode 46
c语言·c++·笔记·学习·算法·leetcode
如何原谅奋力过但无声16 分钟前
TensorFlow 2.x常用函数总结(持续更新)
人工智能·python·tensorflow
程序员-小李26 分钟前
基于 Python + OpenCV 的人脸识别系统开发实战
开发语言·python·opencv
2301_7965125236 分钟前
Rust编程学习 - 内存分配机制,如何动态大小类型和 `Sized` trait
学习·算法·rust
万粉变现经纪人39 分钟前
如何解决 pip install 安装报错 [WinError 32] 文件被占用(杀毒/占用进程)问题
python·pycharm·flask·beautifulsoup·bug·pandas·pip
java1234_小锋1 小时前
[免费]基于Python的Flask酒店客房管理系统【论文+源码+SQL脚本】
开发语言·人工智能·python·flask·酒店客房
秦明月131 小时前
EPLAN电气设计:快捷键版本差异解析
经验分享·学习·学习方法·设计规范
2401_841495642 小时前
【自然语言处理】生成式语言模型GPT复现详细技术方案
人工智能·python·gpt·深度学习·语言模型·自然语言处理·transformer
snakecy2 小时前
过关斩将编程题
开发语言·python