文章目录
- qrc使用介绍
- rcc编译资源
- rcc 的安装与基本使用
- 编译成Python文件
- 使用资源系统文件
- 方式一:导入资源系统文件
- 方式二:整合资源系统文件
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命令名称 |
---|---|
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
。
-
然后,输入以下命令:
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_data
、qt_resource_name
、qt_resource_struct_v1
、qt_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_())
运行结果: