I have been trying to create a minimal multilingual app using Qt Quick. Since I am new to Qt I tried to follow the implementation steps in this blog/tutorial post. However, I cannot get the qsTr() strings to translate when I change the UI language. How can I make all strings wrapped in qsTr() translate when the UI language is changed?
The application does build and run, but the strings are not translated when the button is clicked.
The only issues noted during the build process are the following warnings:
[cmake] Running C:\Qt\Tools\CMake_64\bin\cmake.exe -S C:/BasicMultilingualApp -B C:/BasicMultilingualApp/build/Desktop_Qt_6_8_1_MinGW_64_bit-Debug in C:\BasicMultilingualApp\build\Desktop_Qt_6_8_1_MinGW_64_bit-Debug.[cmake] -- Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR) [cmake] -- Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR)
and
C:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:348: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:847: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:861: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:879: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:893: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:907: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:922: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:936: Ignoring definition of undeclared qualified classC:/Qt/6.8.1/mingw_64/include/QtQml/qqmlprivate.h:950: Ignoring definition of undeclared qualified classUpdating '../../i18n/qml_de_DE.ts'... Found 2 source text(s) (0 new and 2 already existing)Updating '.lupdate/qml_en.ts'... Found 2 source text(s) (2 new and 0 already existing)
System details:
- OS: Windows 11
- Kit: Desktop Qt 6.8.1 MinGW 64-bit
Below I have included the major code components Main.qml and main.cpp along with CMakeLists.txt and the .ts translation file so that my implementation can be easily replicated.
Main.qml
import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: true title: "Basic Multilingual App" // We choose the app title to be language indifferent Component.onCompleted: Qt.uiLanguage = "en" // Set the UI language to English (so that we all start in the same place) Column { anchors.centerIn: parent spacing: 10 Text { id: stringToTranslate //: Example string to translate text: qsTr("This string must be translated on button click") } Button { id: translateText //: Clicking this button translates the text fields text: qsTr("Translate text") onClicked: { Qt.uiLanguage = Qt.uiLanguage === "en" ? "de" : "en" // If UI is English translate to German. Else translate to English console.log(Qt.uiLanguage) // Print the UI language to console so we can monitor its changes } } }}
main.cpp
#include <QGuiApplication>#include <QQmlApplicationEngine>int main(int argc, char *argv[]){ QGuiApplication app(argc, argv); QQmlApplicationEngine engine; QObject::connect(&engine,&QQmlApplicationEngine::objectCreationFailed,&app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.loadFromModule("BasicMultilingualApp", "Main"); return app.exec();}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)project(BasicMultilingualApp VERSION 0.1 LANGUAGES CXX)set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(Qt6 REQUIRED COMPONENTS Quick LinguistTools)qt_standard_project_setup(REQUIRES 6.5 I18N_TRANSLATED_LANGUAGES de_DE)qt_add_executable(appBasicMultilingualApp main.cpp)qt_add_qml_module(appBasicMultilingualApp URI BasicMultilingualApp VERSION 1.0 QML_FILES Main.qml)qt_add_translations(appBasicMultilingualApp TS_FILE_BASE qml TS_FILE_DIR i18n RESOURCE_PREFIX qt/qml/BasicMultilingualApp/i18n LRELEASE_OPTIONS -idbased)# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.# If you are developing for iOS or macOS you should consider setting an# explicit, fixed bundle identifier manually though.set_target_properties(appBasicMultilingualApp PROPERTIES# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appBasicMultilingualApp MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE)target_link_libraries(appBasicMultilingualApp PRIVATE Qt6::Quick)include(GNUInstallDirs)install(TARGETS appBasicMultilingualApp BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
qml_de_DE.ts (German translation file, located in the folder 'i18n'
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE TS><TS version="2.1" language="de_DE"><context><name>Main</name><message><location filename="../Main.qml" line="19"/><source>This string must be translated on button click</source><extracomment>Example string to translate</extracomment><translation>Diese Zeichenfolge muss beim Klicken auf die Schaltfläche übersetzt werden</translation></message><message><location filename="../Main.qml" line="25"/><source>Translate text</source><extracomment>Clicking this button translates the text fields</extracomment><translation>Text übersetzen</translation></message></context></TS>