Не удается прочитать файл с типом extern и системой ресурсов

Я хочу прочитать файл json через систему ресурсов Qt в классе C++.

Предполагать 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

1 ответ

Решение

В " Не удается открыть файл ресурсов" первым решением может быть повторный запуск qmake. Может быть, вероятно, изменить ссылку ссылки с новой информацией о зависимостях.

Вот возможное объяснение. Qt не может устранить неоднозначность ":\Resources\Text\Translation.json" до того, как он прочитает содержимое .qrc даже если .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 ...;
}
Другие вопросы по тегам