Translating Qt applications is quite an easy process that requires only 3 steps and a translator.
Using the lupdate tool, we can create TS files that are readable by QLinguist.
lupdate *.cpp *.h *.ui -ts translations/MyProgram_fr.ts
The translation is made using QLinguist, the graphical tool provided by Qt.
The TS files must now be converted into QM files to be read by our Program at runtime.
With qmake:
TRANSLATIONS = \
../translations/MyProgram_fr.ts
qtPrepareTool(LRELEASE, lrelease)
updateqm.input = TRANSLATIONS
updateqm.output = ${QMAKE_VAR_OBJECTS_DIR}/${QMAKE_FILE_BASE}.qm
updateqm.commands = $$LRELEASE -silent ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
updateqm.CONFIG += no_link target_predeps
QMAKE_EXTRA_COMPILERS += updateqm
With CMake:
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools REQUIRED)
set(TS_FILES MyProgram_fr.ts)
set(PROJECT_SOURCES
traductions/${TS_FILES}
)
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
The program must be started with the correct language to have an adequate translation. The easiest way is to:
We need to tell the program where are the translations relative to the executable (the QM files must be copied in these locations for deployment):
void MainWindow::loadLanguages() {
lang = settings->value("settings/language", "en").toString(); // Read language from QSettings
QString appDir = QCoreApplication::applicationDirPath();
QStringList translationLocation = {appDir, appDir + "/../Resources/", appDir + "/../share/openjournal/"}; // Different OS, different path {Windows, Mac bundle, Linux}
for (auto const &a : translationLocation) { // Read from the three locations
QStringList availableLang = QDir(a).entryList({"*.qm"}); // Find all qm files
if (!availableLang.isEmpty()) {
translator.load("openjournal_" + lang, a); // Load translation
QLocale::setDefault(QLocale(lang)); // Set the default locale
this->setLocale(QLocale(lang)); // Set the widget's locale
qApp->installTranslator(&translator); // Apply translation
for (const auto &i : availableLang) { // Append one action by language in a menu, if clicked, change settings language then reboot to apply the change
QAction *langAction = new QAction(i.mid(12, 2), this);
langAction->setCheckable(true);
if (lang == i.mid(12, 2)) {
langAction->setChecked(true);
}
connect(langAction, &QAction::triggered, [this, i]() {
lang = i.mid(12, 2);
settings->setValue("lang");
qApp->quit(); // Quit app
QProcess::startDetached(qApp->arguments()[0], qApp->arguments()); // Restart app
});
ui->menuLanguage->addAction(langAction);
}
}
}
}
Once the translation process is implemented, the translation task can be performed without modifying the code. QLinguist allows non-technical users to generate and translate TS files that will be transformed automatically in QM files used at runtime to load translation.