如何从非Qt函数访问Qt资源数据

daj*_*daj 10 c++ qt packaging

据我了解,在Qt应用程序中打包非代码资源(如数据文件)的方法是使用资源系统.但是,如果我想使用非Qt函数访问资源该怎么办?例如,我可能有一个.txt或.csv文件,其中包含一些我想使用ifstream访问的应用程序数据.似乎不能使用":..."语法代替非Qt函数和类的文件名.是否有单独的工作流程来打包应用程序中非Qt函数使用的数据?

我正在使用OSX,但我认为这些问题与平台无关.

Rei*_*ica 6

Qt 资源系统的唯一目的是在可执行文件本身内捆绑数据。如果您不希望将数据集成到可执行文件中,那么您绝对不能使用资源系统。

在 Mac 上,如果您希望将项目源中的“data.txt”添加到您的应用程序包中,而不是添加到可执行文件本身,请将以下内容添加到您的.pro文件中:

mac {
    BUNDLE = $$OUT_PWD/$$TARGET$$quote(.app)/Contents
    QMAKE_POST_LINK += ditto \"$$PWD/data.txt\" \"$$BUNDLE/Resources/\";
}
Run Code Online (Sandbox Code Playgroud)

给定上面的项目文件,使用QCoreApplication::applicationDirPath()for 获取文件的有用路径:

#include <QCoreApplication>
#include <QFile>
#include <QDebug>

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   qDebug() << QCoreApplication::applicationDirPath();
   QFile data(QCoreApplication::applicationDirPath() + "/../Resources/data.txt");
   if (data.open(QIODevice::ReadOnly | QIODevice::Text))
      qDebug() << data.readAll();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,Resources文件夹与 Qt 资源系统无关。这只是 OS X 应用程序包中的命名约定。我们在这里没有使用 Qt 资源系统。

如果您希望使用 Qt 资源系统并直接访问资源数据而不是通过QFileQResource该类提供对捆绑在可执行文件中的资源的访问。

如果您控制的代码坚持ifstream用于数据输入,那么它是人为限制的,应该修复。它应该istream改为使用,因为该类可以由任何东西支持,不一定是文件。如果是您无法控制的代码,则可以ifstreamQLocalSocket.

您可以通过流缓冲区将常量映射QResource::data() 到输入流

如果是资源isCompressed(),那么你需要先将它解压到一个临时区域。您还可以禁用资源压缩以避免解压步骤。您可以改用像upx这样的完整可执行压缩器- 当您的代码运行时,所有内容都已经解压缩并可以使用。