如何将 qrc 数据包含到使用 CMake 编译的基于 Qt 的二进制文件中
Posted
技术标签:
【中文标题】如何将 qrc 数据包含到使用 CMake 编译的基于 Qt 的二进制文件中【英文标题】:How to include qrc data into Qt-based binary that was compiled using CMake 【发布时间】:2016-02-05 17:14:31 【问题描述】:我有一个大型 Qt + 第三方库项目,我尝试将其编译为二进制文件,以便在另一台机器上测试该程序。我能够运行二进制文件(找到所有必要的*.dll
s 和插件),但是,我无法弄清楚如何为我的程序包含带有图标的*.qrc
数据。目前,二进制文件无法加载任何图标,所以我只有带有文本的按钮。
我的程序代码结构如下:
根文件夹CMakeLists.txt
程序文件夹
main.cpp
CMakeLists.txt
data_folder / Data.qrc
和svg
格式的图标集
其他.cpp
和.h
文件
lib_folder1
lib_folder2
...
这是Data.qrc
文件内部的样子:
RCC>
<qresource prefix="/">
<file>file-name.svg</file>
...
这就是我将资源添加到我的程序中的方式,在 program_folder 的 CMakeLists.txt
内:
qt5_add_resources(IMG_RSC_ADDED data_folder/Data.qrc )
add_executable($PROJECT_NAME $PROJECT_SRCS $IMG_RSC_ADDED )
在 program_folder 的 .cpp
文件之一中,我加载了图标:
static QIcon icon(QPixmap(":/file-name.svg"));
对于图标,我有一个class Data;
,在该类中我有一组方法,例如static const QIcon& fileIcon();
。而在主代码中,当我需要使用图标时,我是这样称呼的:Data::fileIcon()
。
当我从源代码编译和运行时它可以工作。
我准备了我的程序的二进制发行版,这就是它在某个根文件夹中的结构:
图像格式qsvg.dll
平台
qwindows.dll
my_program.exe
Qt5Core.dll
其他 Qt 和 3rd-party-lib dll
s
我的问题是如何以及在哪里放置数据文件?我尝试了不同的位置,例如,在主文件夹内,在创建的 Data
文件夹内。我只是复制了我拥有的所有数据(svg
文件,qrc
文件),但二进制文件仍然看不到资源。如何解决?或者,常见的做法是什么?
注意,我使用 CMake(不是 QMake)来编译我的二进制文件。我在 Windows 7 上使用 Qt-5.4。如果我的问题缺少详细信息,请告诉我,我会添加它们。谢谢!
【问题讨论】:
我不明白你的问题,qrc资源默认嵌入到二进制中。你说的是什么数据文件? 如果它们是嵌入的,那么为什么二进制找不到它们?数据文件是指 svg 文件,因为这就是我的代码中引用它们的方式,例如,QPixmap(":/file-name.svg")
。
这是另一回事,应该调查,但qt5_add_resources
行执行以下操作:它从提供的 qrc 文件生成所有资源的二进制数据,并将此数据输出到列表中的字段存储在您的IMG_RSC_ADDED
中。您可以通过使用消息命令打印它来检查它包含的内容:message($IMG_RSC_ADDED)
我不喜欢你代码中的 static QIcon。您是否在函数或全局范围内拥有它们?
静态成员初始化顺序未定义,但保证在主启动之前完成,并且您正在使用需要创建和运行 QApplication 的 QPixmap。因此,在进行任何进一步调查之前,首先尝试将至少几个 QIcon 的初始化放在类构造函数中。因此,您将拥有这样的 QIcon:static QIcon icon;
并在 ctor 中初始化它:icon = QIcon(QPixmap(":/file-name.svg"));
并看到它有帮助
【参考方案1】:
以下命令qt5_add_resources(IMG_RSC_ADDED data_folder/Data.qrc)
使具有二进制数据的源文件从提供的 qrc 文件(在本例中为 Data.qrc)的每个资源中生成,并且生成的文件列表存储在 IMG_RSC_ADDED
变量中。只要将此变量传递给add_executable
,所有资源都会嵌入到生成的二进制文件中。
接下来是实际问题:问题不在于发行版,而在于代码本身。您在静态上下文中创建并初始化QIcon
s 并使用QPixmap
,但QPixmap
需要QApplication
启动并运行,而静态初始化上下文并非如此。所以正确的解决方法是将 QIcon
s 的初始化移动到一些本地上下文(如类 ctor 或主函数)
【讨论】:
以上是关于如何将 qrc 数据包含到使用 CMake 编译的基于 Qt 的二进制文件中的主要内容,如果未能解决你的问题,请参考以下文章
CMake 是不是将包含的标头中的所有内容编译到可执行文件中,还是仅将主类中使用的部分编译为可执行文件?
如何使用 pandas read_pickle 从 qrc 资源文件中读取包含 pandas 数据框的 pickle 文件?