【问题标题】:Can not read file with extern type and resource system无法读取外部类型和资源系统的文件
【发布时间】:2016-09-29 16:23:32
【问题描述】:

我想在一个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

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

注意:

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

【问题讨论】:

  • 可能是全局变量初始化的顺序问题。一个解决方案可能是在所有其他全局变量之后初始化 _tr。例如:用Translator* _tr = nullptr; 声明它并在main 的开头或在使用它的第一个函数中调用_tr = new Translator
  • @Frank.Could 你再看看我的 Translator.h。实际上我希望在我们包含 Translator.h 的每个源文件中,我们将能够使用 Tr() 函数并在 main 中初始化或在我的情况下无法在每个源文件中进行初始化
  • 例如,您可以使用if (!_tr) _tr = new Tranlator; return _tr-&gt;valueAt... 定义Tr(...)。这只是隔离问题的第一个建议。
  • @frank.如果我将文件(在构造函数中)声明为完整路径,例如 ""C:/Users//Documents/Resources/Text/Translation.json “没有更多的错误。你知道为什么会这样吗?
  • 我不知道QIODevice,但它可能使用全局变量初始化步骤中定义的资源来从相对路径中找到完整路径。我用谷歌搜索。

标签: c++ qt qt5 qfile qt-resource


【解决方案1】:

Cannot open resource file 中,第一个解决方案可以是再次运行 qmake。可能会使用新的依赖信息更改链接版本。

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

所以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 ...;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    相关资源
    最近更新 更多