2016-09-29 4 views
1

Я хочу прочитать файл 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

Однако, когда я удалить Экстерн Translator объекта и создать, что в основной функции или когда заменить путь «Ресурсы/Текст/Translation.json» с полным путем там больше нет ошибки

Примечания:

может быть хорошим, чтобы сказать, что я хочу, чтобы прочитать Translator.json один раз в моей заявке, и для этого я создать extern Translator

+1

Это может быть проблема упорядочения в инициализации глобальных переменных. Решением может быть инициализация '_tr' после всех других глобальных переменных. ex: объявить его с помощью 'Translator * _tr = nullptr;' и вызывать '_tr = новый переводчик' в начале' main' или в первой функции, которая его использует. – Franck

+0

@ Фрэнк. Не могли бы вы еще раз взглянуть на мой Translator.h.actually, я хочу, чтобы в каждом исходном файле мы включали Translator.h, мы сможем использовать функцию Tr(), а инициализация в main или инициализация в каждом исходном файле невозможно для моего случая – IMAN4K

+0

Вы можете, например, определить 'Tr (...)' с 'if (! _tr) _tr = новый Tranlator; return _tr-> valueAt ... '. Это просто первое предложение, чтобы изолировать проблему. – Franck

ответ

1

в Cannot open resource file, первый Солу может быть снова запустить 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 ...; 
} 
Смежные вопросы