构建应用程序需要的不仅仅是代码。通常情况下,你的界面将需要动作的图标,你可能想添加插图或品牌标识,或者你的应用程序将需要加载数据文件来预先填充小工具。这些数据文件与你的应用程序的源代码是分开的,但最终需要与它一起打包和分发,以便它能够工作。
与应用程序一起分发数据文件是造成问题的一个常见原因。如果你用路径引用数据文件,你的应用程序将无法正常工作,除非目标计算机上有完全相同的路径。在为跨平台(Windows、macOS和Linux)的应用打包时,这可能变得更加棘手。值得庆幸的是,Qt用它的资源系统来拯救我们。资源被捆绑在Python文件中,可以和你的源代码一起发布,保证它们在其他平台上继续工作。你可以通过Qt Designer管理资源,并使用资源库在你的应用程序中加载图标(和其他数据)。
示例应用程序
为了演示如何使用资源系统,我们将创建一个简单的应用程序,它使用两个数据文件--在本例中是两个图标图像文件。然而,请记住你可以把任何类型的数据打包成资源,包括你的应用程序所依赖的数据文件。
下面的例子显示了一个单一的按钮,按下后会改变它的图标。
import sys
from PySide6 import QtGui, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello World")
self.button = QtWidgets.QPushButton("My button")
icon = QtGui.QIcon("animal-penguin.png")
self.button.setIcon(icon)
self.button.clicked.connect(self.change_icon)
self.setCentralWidget(self.button)
self.show()
def change_icon(self):
icon = QtGui.QIcon("animal-monkey.png")
self.button.setIcon(icon)
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec_()
复制代码
把这个文件保存到你的电脑上,称为app.py
。运行它,你会看到窗口中出现了按钮,但没有图标可见。这就是当你用找不到的文件创建QIcon()
对象时发生的情况--它们被简单地省略了。如果你在打包你的应用程序时遇到问题,这对你来说会很熟悉。
没有可用的图标,什么都不会显示。
下载并放置animal-penguin.png和animal-monkey.png图标到与脚本相同的文件夹中,然后再次运行它。*这些图标来自Yusuke Kamiyamane的Fugue图标集。*再次运行该程序,你会如愿看到这些图标。
由于图标与脚本在同一个文件夹中,现在可以看到它们了。
现在应用程序如期工作了,我们将改用QResource
系统来加载这两个文件。首先,我们需要定义我们的QRC文件,并将我们的资源添加到其中。
这对于2个文件来说可能看起来是多余的,但随着你的项目越来越大,其优势也就越来越明显了
QRC文件
Qt资源系统的核心是资源文件或QRC。.qrc
文件是一个简单的XML文件,可以在任何文本编辑器中打开。
你也可以使用Qt Designer创建QRC文件并添加和删除资源,这一点我们将在后面介绍。
简单的QRC例子
一个非常简单的资源文件如下所示,它包含一个单一的资源(一个我们可能添加到按钮上的单一图标animal-penguin.png
)。
xml
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="icons">
<file alias="animal-penguin.png">animal-penguin.png</file>
<file alias="animal-monkey.png">animal-monkey.png</file>
</qresource>
</RCC>
复制代码
<file>
</file>
标签之间的名称是文件的路径,相对于资源文件而言。alias
是这个资源的名称,在你的应用程序中会被知道。你可以在你的应用程序中使用这个重命名图标,使其更符合逻辑或更简单,而在外部则保持原来的名称。
例如,如果我们想在内部使用penguin.png
这个名字,我们可以把这几行改为。
xml
<file alias="penguin.png">animal-penguin.png</file>
<file alias="monkey.png">animal-monkey.png</file>
复制代码
这只是改变你的应用程序中使用的名称,文件名保持不变。
在这个标签外面是qresource
,它指定了一个prefix
。这是一个命名空间,可以用来将资源分组。这实际上是一个虚拟文件夹,在这个文件夹下可以找到所有嵌套的资源。在我们目前的结构中,我们的两个图标被分组在虚拟文件夹icons/
。
将下面的文件保存为resources.qrc
,这就是我们的资源文件,从现在开始我们将使用它。
xml
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="icons">
<file alias="penguin.png">animal-penguin.png</file>
<file alias="monkey.png">animal-monkey.png</file>
</qresource>
</RCC>
复制代码
使用QRC文件
要在你的应用程序中使用一个.qrc
文件,你首先需要把它编译成Python。PySide提供了一个命令行工具来完成这个工作,它接受一个.qrc
文件作为输入,并输出一个包含编译后数据的Python文件。然后可以像其他Python文件或模块一样将其导入你的应用程序中。
要把我们的resources.qrc
文件编译成一个名为resources.py
的 Python 文件,我们可以使用 --
bash
pyside6-rcc resources.qrc -o resources.py
复制代码
为了在我们的应用程序中使用这个资源文件,我们需要做一些小的改动。首先,我们需要在我们的应用程序的顶部import resources
,将资源加载到Qt资源系统中,其次,我们需要更新图标文件的路径,以使用资源路径格式,如下。
前缀:/
,表示这是一个资源路径。第一个名字 "icons "是前缀命名空间,文件名取自文件别名,都是我们的resources.qrc
文件中定义的。
更新后的应用程序如下图所示。
蟒蛇
import sys
from PySide6 import QtGui, QtWidgets
import resources
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Hello World")
self.button = QtWidgets.QPushButton("My button")
icon = QtGui.QIcon(":/icons/penguin.png")
self.button.setIcon(icon)
self.button.clicked.connect(self.change_icon)
self.setCentralWidget(self.button)
self.show()
def change_icon(self):
icon = QtGui.QIcon(":/icons/monkey.png")
self.button.setIcon(icon)
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec_()
复制代码
如果你现在运行这个程序,它看起来和以前一模一样,但现在图标是从resources.py
编译资源文件中加载的。
图标可见,从QRC文件中加载。
Qt Designer和Qt Creator中的资源
虽然通过直接编辑QRC文件来管理你的资源是相当直接的,但Qt Designer也可以用来编辑资源库。这使你能够直观地看到所有的图标(和其他数据),重新排列它们,并通过拖放来编辑它们。
在Qt Designer中添加资源
如果你使用的是独立的Qt Designer,资源浏览器可以作为一个可停靠的部件,默认在右下角可见。如果资源浏览器被隐藏,你可以通过工具栏上的 "查看 "菜单来显示它。
要添加、编辑和删除资源文件,请点击资源浏览器面板上的铅笔图标。这将打开资源编辑器。
独立的Qt Designer视图
在资源编辑器视图中,你可以通过点击左下角的文档文件夹图标(中间的图标)来打开一个现有的资源文件。
在Qt Designer中编辑资源
在左边的面板上,你也可以从你的用户界面上创建和删除资源文件。而在右边,你可以创建新的前缀,将文件添加到前缀并删除项目。对资源文件的修改会自动保存。
在Qt Creator中添加资源
为了能够在Qt Creator中使用Qt资源系统添加图标,你需要有一个活跃的Qt项目,并将你的用户界面和资源文件都添加到其中。
如果你没有建立一个Qt Creator项目,你可以在你现有的源代码文件夹中创建一个。Qt Creator会在覆盖你的任何文件之前进行提示。点击 "+ New",为项目类型选择 "Qt for Python - Empty"。在 "Create in "中选择你的源文件夹上面的文件夹,并提供你的源文件夹的名称作为项目名称。你可以删除任何创建的文件,除了存放项目设置的.pyproject
。
选择位置
要向你现有的项目添加资源,选择左手面板上的 "编辑 "视图。你会在左手面板上看到一个文件树浏览器。右击文件夹,选择 "添加现有文件......",将你现有的.qrc
文件添加到项目中。
编辑视图,显示添加的文件
当你在这里添加/删除东西时,用户界面并不更新,这似乎是Qt Creator的一个错误。如果你关闭并重新打开Qt Creator,文件会在那里。
一旦你把QRC文件添加到文件列表中,你就可以像扩展一个文件夹一样扩展该文件,并浏览其中的资源。你也可以用这个界面添加和删除资源。
在Qt Creator和Qt Designer中使用资源
一旦资源文件被加载,你将能够从设计器的属性中访问它。下面的截图显示了设计器中打开了我们的计数器应用,并选择了增量按钮。按钮的图标可以通过点击黑色小的向下箭头并选择 "选择资源... "来选择。
选择位置
出现的资源选择器窗口允许你从项目中的资源文件中挑选图标用于你的用户界面。
选择位置
以这种方式从资源文件中选择图标,可以确保它们总是有效的,只要你编译并将编译后的资源文件与你的应用程序捆绑在一起。
将QRC文件与已编译的UI文件一起使用
如果你在Qt Designer中设计你的UI,并将生成的UI文件编译为Python,那么UI编译器会自动为你的Qt资源文件的编译版本添加导入。例如,如果你运行下面的 --
bash
pyside6-uic mainwindow.ui -o MainWindow.py
复制代码
这个构建过程也会为UI中使用的资源的编译版本添加导入到MainWindow.py
,在我们的例子中是resources.qrc
。这意味着你不需要将这些资源单独导入你的应用程序中。然而,我们仍然需要构建它们,并使用MainWindow.py
中用于导入的特定名称,这里是resources_rc
。
bash
pyside6-rcc resources.qrc -o resources_rc.py
复制代码
命令行工具在为资源文件添加导入时遵循的模式是<resource name>_rc.py
,所以你在自己编译资源时也需要遵循这个模式。如果有问题,你可以检查你编译的UI文件(例如:MainWindow.py
)来仔细检查导入的名称。
什么时候使用QResource
?
你可能想知道何时(甚至是否)应该使用QResource
系统。
主要的优势是在打包和分发你的应用程序时。因为你的数据与Python源代码捆绑在一起,你消除了所有潜在的路径问题,保证你的数据文件可以被你的应用程序访问。你还可以使用Qt Designer来管理和分组你的应用程序的图标。当然,缺点是当你添加/删除新资源时,你需要重新编译你的资源。
这种权衡对你的项目来说是否值得,取决于你自己,但如果你打算把你的应用程序分发给其他人,那几乎总是值得的。