如何将 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 + 第三方库项目,我尝试将其编译为二进制文件,以便在另一台机器上测试该程序。我能够运行二进制文件(找到所有必要的*.dlls 和插件),但是,我无法弄清楚如何为我的程序包含带有图标的*.qrc 数据。目前,二进制文件无法加载任何图标,所以我只有带有文本的按钮。

我的程序代码结构如下:

根文件夹 CMakeLists.txt 程序文件夹 main.cpp CMakeLists.txt data_folder / Data.qrcsvg 格式的图标集 其他.cpp.h 文件 lib_folder1 lib_folder2 ...

这是Data.qrc 文件内部的样子:

RCC>
<qresource prefix="/">
    <file>file-name.svg</file>
    ...

这就是我将资源添加到我的程序中的方式,在 program_folderCMakeLists.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&amp; fileIcon();。而在主代码中,当我需要使用图标时,我是这样称呼的:Data::fileIcon()

当我从源代码编译和运行时它可以工作。

我准备了我的程序的二进制发行版,这就是它在某个根文件夹中的结构:

图像格式 qsvg.dll 平台 qwindows.dll my_program.exe Qt5Core.dll 其他 Qt 和 3rd-party-lib dlls

我的问题是如何以及在哪里放置数据文件?我尝试了不同的位置,例如,在主文件夹内,在创建的 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,所有资源都会嵌入到生成的二进制文件中。

接下来是实际问题:问题不在于发行版,而在于代码本身。您在静态上下文中创建并初始化QIcons 并使用QPixmap,但QPixmap 需要QApplication 启动并运行,而静态初始化上下文并非如此。所以正确的解决方法是将 QIcons 的初始化移动到一些本地上下文(如类 ctor 或主函数)

【讨论】:

以上是关于如何将 qrc 数据包含到使用 CMake 编译的基于 Qt 的二进制文件中的主要内容,如果未能解决你的问题,请参考以下文章

Qt5 将 qrc 移至 DLL

CMake 是不是将包含的标头中的所有内容编译到可执行文件中,还是仅将主类中使用的部分编译为可执行文件?

如何使用 pandas read_pickle 从 qrc 资源文件中读取包含 pandas 数据框的 pickle 文件?

无法在 Qt C++ 程序中加载 qrc 文件

使用 cmake (windows) 构建时不显示 Qt 资源

使用 Cmake,如何防止库源包含在我的 IDE 中?