Correct way to load .qm files in QTranslator
-
Hello!
I am adding translation layer to my Qt6/QML application and I'm having issues loading my .em file.
I am following the QML documentation, which is lacking for Localization, to say the least. The closest thing I found for me as I only need to use .qml file localization is (https://doc.qt.io/qt-6/qtlinguist-arrowpad-example.html) and (https://doc.qt.io/qt-6/qtqml-qml-i18n-example.html)
Things I've done:
- Include LinguistsTools in CMake (Works)
- Added this to my CMakeLists.txt (It builds the .em file in my build folder)
qt6_add_translations(${CMAKE_PROJECT_NAME} TS_FILES qml/translations/EN_en.ts )- Added this to my main.cpp (Doesn't work!)
QTranslator translator; QString translationPath = app.applicationDirPath() + "/EN_en.qm"; if (translator.load(translationPath)) { app.installTranslator(&translator); SPDLOG_INFO("Translator loaded"); } else { SPDLOG_ERROR("Failed to load translator"); }This command
translator.load(translationPath)returns false.I'm pretty sure my path is wrong here - how can I add correct .em file path? I don't want to hardcode it, I want to be relative - how can I get the build folder via QApplication object? Or maybe is it better to define it in QRC file and use qrc:/translations/EN_en.qm or something like that? If so, then is it a good idea to add build folder files in QRC - isn't that against the standard? In the future I will want to add translations to other languages as well so I want to get the .em file saving right.
This is my EN_en.ts file:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="en"> <context> <name>Test</name> <message> <source>Hello World</source> <translation>Hello World EN</translation> </message> <message> <source>Goodbye</source> <translation>Goodbye EN</translation> </message> </context> </TS>In QML I am testing like this - it should be Hello World EN when I get it working.
text: qsTr("Hello World") -
@Christian-Ehrlicher Yes, it's in int main(), same as the QApplication. Ok, thanks for showing that it adds it to resource file automatically. Unfortunately it still doesn't work. Now I have this setup:
CMakeLists.txt
qt6_add_translations(${CMAKE_PROJECT_NAME} TS_FILES qml/translations/EN_en.ts RESOURCE_PREFIX "/translations" )main.cpp [int main()] -
translator.load("qrc:/translations/EN_en")still returnsfalse:(... QTranslator translator; if (translator.load("qrc:/translations/EN_en")) { app.installTranslator(&translator); SPDLOG_INFO("Translator loaded"); } else { SPDLOG_ERROR("Failed to load translator"); } ...@therealmatiss , try
if (translator.load(":/translations/EN_en.qm")) { -
Hello!
I am adding translation layer to my Qt6/QML application and I'm having issues loading my .em file.
I am following the QML documentation, which is lacking for Localization, to say the least. The closest thing I found for me as I only need to use .qml file localization is (https://doc.qt.io/qt-6/qtlinguist-arrowpad-example.html) and (https://doc.qt.io/qt-6/qtqml-qml-i18n-example.html)
Things I've done:
- Include LinguistsTools in CMake (Works)
- Added this to my CMakeLists.txt (It builds the .em file in my build folder)
qt6_add_translations(${CMAKE_PROJECT_NAME} TS_FILES qml/translations/EN_en.ts )- Added this to my main.cpp (Doesn't work!)
QTranslator translator; QString translationPath = app.applicationDirPath() + "/EN_en.qm"; if (translator.load(translationPath)) { app.installTranslator(&translator); SPDLOG_INFO("Translator loaded"); } else { SPDLOG_ERROR("Failed to load translator"); }This command
translator.load(translationPath)returns false.I'm pretty sure my path is wrong here - how can I add correct .em file path? I don't want to hardcode it, I want to be relative - how can I get the build folder via QApplication object? Or maybe is it better to define it in QRC file and use qrc:/translations/EN_en.qm or something like that? If so, then is it a good idea to add build folder files in QRC - isn't that against the standard? In the future I will want to add translations to other languages as well so I want to get the .em file saving right.
This is my EN_en.ts file:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="en"> <context> <name>Test</name> <message> <source>Hello World</source> <translation>Hello World EN</translation> </message> <message> <source>Goodbye</source> <translation>Goodbye EN</translation> </message> </context> </TS>In QML I am testing like this - it should be Hello World EN when I get it working.
text: qsTr("Hello World")@therealmatiss said in Correct way to load .qm files in QTranslator:
QTranslator translator
How long does this object live?
-
@therealmatiss said in Correct way to load .qm files in QTranslator:
QTranslator translator
How long does this object live?
@Christian-Ehrlicher Until the end of program. It's not a problem about QTranslator - it's a problem about loading the .em file.
There is nothing in documentation about the pathing of .qm files - where they are generated, where they should be located preferably, how they should be preferably loaded. Most of the tutorials are based from pre-Qt6 time with .pro files. For example, this (https://doc.qt.io/qt-6/qtqml-qml-i18n-example.html) is unfinished - it doesn't even show QTranslator object creation, let alone loading the .qm files.
I just want an example on how to add .ts files to QML in Qt6 using CMake - I am not using the device locale.
EDIT: I figured that I add that
translator.load(translationPath)returns false. Must be my translationPath issue. -
@Christian-Ehrlicher Until the end of program. It's not a problem about QTranslator - it's a problem about loading the .em file.
There is nothing in documentation about the pathing of .qm files - where they are generated, where they should be located preferably, how they should be preferably loaded. Most of the tutorials are based from pre-Qt6 time with .pro files. For example, this (https://doc.qt.io/qt-6/qtqml-qml-i18n-example.html) is unfinished - it doesn't even show QTranslator object creation, let alone loading the .qm files.
I just want an example on how to add .ts files to QML in Qt6 using CMake - I am not using the device locale.
EDIT: I figured that I add that
translator.load(translationPath)returns false. Must be my translationPath issue.@therealmatiss said in Correct way to load .qm files in QTranslator:
Until the end of program.
Not if your snippet you showed us is in a function.
The cmake macro adds the qm file to the resource file so your path is wrong: https://doc.qt.io/qt-6/qtlinguist-cmake-qt-add-translations.html#embedding-generated-qm-files-in-resources
-
@therealmatiss said in Correct way to load .qm files in QTranslator:
Until the end of program.
Not if your snippet you showed us is in a function.
The cmake macro adds the qm file to the resource file so your path is wrong: https://doc.qt.io/qt-6/qtlinguist-cmake-qt-add-translations.html#embedding-generated-qm-files-in-resources
@Christian-Ehrlicher Yes, it's in int main(), same as the QApplication. Ok, thanks for showing that it adds it to resource file automatically. Unfortunately it still doesn't work. Now I have this setup:
CMakeLists.txt
qt6_add_translations(${CMAKE_PROJECT_NAME} TS_FILES qml/translations/EN_en.ts RESOURCE_PREFIX "/translations" )main.cpp [int main()] -
translator.load("qrc:/translations/EN_en")still returnsfalse:(... QTranslator translator; if (translator.load("qrc:/translations/EN_en")) { app.installTranslator(&translator); SPDLOG_INFO("Translator loaded"); } else { SPDLOG_ERROR("Failed to load translator"); } ... -
@Christian-Ehrlicher Yes, it's in int main(), same as the QApplication. Ok, thanks for showing that it adds it to resource file automatically. Unfortunately it still doesn't work. Now I have this setup:
CMakeLists.txt
qt6_add_translations(${CMAKE_PROJECT_NAME} TS_FILES qml/translations/EN_en.ts RESOURCE_PREFIX "/translations" )main.cpp [int main()] -
translator.load("qrc:/translations/EN_en")still returnsfalse:(... QTranslator translator; if (translator.load("qrc:/translations/EN_en")) { app.installTranslator(&translator); SPDLOG_INFO("Translator loaded"); } else { SPDLOG_ERROR("Failed to load translator"); } ...@therealmatiss , try
if (translator.load(":/translations/EN_en.qm")) { -
@kkoehne Sorry for the late response but thank you! It now loads correctly.
Is it that
QResources, which are not defined in.qrcfile, are accessible by:instead ofqrc:? I have only been using resources viaqrcfile so I haven't experienced this before. I suggest to add here (https://doc.qt.io/qt-6/qtlinguist-cmake-qt-add-translations.html#embedding-generated-qm-files-in-resources) an example on how to load correct auto-added .qm resource path, after generating .qm file.There are a few more things I would like to add - please, provide a
.tsfile example in the documents (there's one that only explains all parameters but doesn't show an example) -
T therealmatiss has marked this topic as solved on
-
@kkoehne Sorry for the late response but thank you! It now loads correctly.
Is it that
QResources, which are not defined in.qrcfile, are accessible by:instead ofqrc:? I have only been using resources viaqrcfile so I haven't experienced this before. I suggest to add here (https://doc.qt.io/qt-6/qtlinguist-cmake-qt-add-translations.html#embedding-generated-qm-files-in-resources) an example on how to load correct auto-added .qm resource path, after generating .qm file.There are a few more things I would like to add - please, provide a
.tsfile example in the documents (there's one that only explains all parameters but doesn't show an example)@therealmatiss said in Correct way to load .qm files in QTranslator:
Is it that QResources, which are not defined in .qrc file, are accessible by : instead of qrc:?
No, it's simpler: qrc:/ is a URL, :/ is a (special) file path. API's expecting a file path (QString) only acknowledge :/, while API's expecting a URL (QUrl) only acknowledge qrc:/. Traditional API's in Qt Core typically expect QString, while QML slowly moved towards QUrl for network transparency, so it became rather confusing :/
-
@therealmatiss said in Correct way to load .qm files in QTranslator:
Is it that QResources, which are not defined in .qrc file, are accessible by : instead of qrc:?
No, it's simpler: qrc:/ is a URL, :/ is a (special) file path. API's expecting a file path (QString) only acknowledge :/, while API's expecting a URL (QUrl) only acknowledge qrc:/. Traditional API's in Qt Core typically expect QString, while QML slowly moved towards QUrl for network transparency, so it became rather confusing :/
@kkoehne Thank you for the explanation!