1

我想通过 C++ 类中的 Qt 资源系统读取 json 文件。

假设Translator.h

    class Translator
    {
    public:
        Translator();
    
        void read(const QString &fpath);
        QString valueAt(const QString &key) const;
    
    };
    
    extern Translator _tr;

    inline QString Tr(const QSTring &key) {
        return _tr.valueAt(key);
}

并且Translator.cpp

Translator::Translator() {
    read(":/Resources/Text/Translation.json");
}

void Translator::read(const QString &fpath) {
    QFile f(fpath);
    f.open(QIODevice::ReadOnly | QIODevice::Text);
    f.readAll(); // f.errorString() -> no such file or directory
    f.close();
}

Translator _tr;

还有.qrc文件:.qrc:

<RCC version="1.0">
    <qresource>
    <file>Resources/Text/Translation.json</file>
    </qresource>
</RCC>

每次我运行上面的代码时都会出错:

QIODevice::read (QFile, ":\Resources\Text\Translation.json"): device not open

但是,当我删除外部Translator对象并在主函数中创建它或将路径“Resources/Text/Translation.json”替换为完整路径时,不会再出现错误

笔记:

可能值得一提的是,我想Translator.json在整个应用程序中阅读一次,为此我创建了一个extern Translator

4

1 回答 1

1

无法打开资源文件中,第一个解决方案可以是再次运行 qmake。可能会使用新的依赖信息更改链接版本。

这是一个可能的解释。.qrc即使.qrc在可执行文件中编译,Qt 也无法在读取内容之前消除 ":\Resources\Text\Translation.json" 的歧义。

所以QFile应该需要(可能在初始化全局变量的步骤中)初始化来构建一个内部映射(名称->文件)。

如果您的初始化Translator _tr;发生在此地图初始化之前,则会出现错误。如果它发生在之后,事情应该会奏效。

另一种解决方案可能是

class Translator
{
public:
    Translator();

    void read(const QString &fpath);
    QString valueAt(const QString &key) const;
private:
    bool m_ready;
};

Translator::Translator() : m_ready(false) {}

void Translator::read(const QString &fpath) {
    QFile f(fpath);
    f.open(QIODevice::ReadOnly | QIODevice::Text);
    f.readAll(); // f.errorString() -> no such file or directory
    f.close();
}

QString Translator::valueAt(const QString &key) const {
    if (!m_ready) {
      m_ready = true;
      read(":/Resources/Text/Translation.json");
    }
    ...
    return ...;
}
于 2016-09-29T17:36:11.447 回答