I want to read a json file via Qt resource system in a c++ class.
Assume 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);
}
And 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;
And also .qrc
file:
.qrc:
<RCC version="1.0">
<qresource>
<file>Resources/Text/Translation.json</file>
</qresource>
</RCC>
Every time i run above code i get error :
QIODevice::read (QFile, ":\Resources\Text\Translation.json"): device not open
However when i remove extern Translator
object and create that in main function or when replace the path "Resources/Text/Translation.json" with full path there is no more error
might be good to mention that i want to read Translator.json
one time in my whole application and for that i create an extern Translator
In Cannot open resource file, a first solution can be to run qmake again. It is maybe likely to change the link edition with new dependency information.
Here is a possible explanation. Qt cannot disambiguate ":\Resources\Text\Translation.json" before it reads the content of the .qrc
even if the .qrc
is compiled in the executable.
So QFile
should need (probably during the step of the initialization of the global variables) an initialization to build an internal map (name -> file).
If your initialization of Translator _tr;
occurs before this map initialization, you have the error. If it occurs after, things should work.
Another solution could be
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 ...;
}