Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Initial translation language with QTranslator
Forum Updated to NodeBB v4.3 + New Features

Initial translation language with QTranslator

Scheduled Pinned Locked Moved Solved General and Desktop
qtranslator
9 Posts 3 Posters 1.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    oserrabassa
    wrote on last edited by oserrabassa
    #1

    I have been spending several hours trying to understand how translations work in Qt and how to set them up properly.

    However, I am stuck on setting the initial translation language of a QML Qt Quick application using QTranslator. The weird thing is that the resource with the translations is created successfully and even the terminal tells me that the initial translation language has been loaded (finnish in my project). But the project is still using the raw translation string values that I used to code the application, which is English.

    QTranslator translator;
    if (translator.load(":/qt/qml/Translations/i18n/qml_fi.qm")) {
        app.installTranslator(&translator);
        qDebug() << "Finnish translation loaded at startup";
    } else {
        qWarning() << "Failed to load Finnish translation at startup";
    }
    

    If I try to change the language by pressing one of the bottom buttons which change the language in QML by updating Qt.uiLanguage, the application then changes language. Therefore, I know that my .qm translation files are not the issue. The problem seems to be that this initial translation language, for whatever reason, is getting ignored.

    Here is my very simple sample project which derivates from the Translation tutorial provided by Qt Academy. If I had to say, I guess there is something wrong with either CMakeLists.txt or the main.cpp file, but they look good to me.

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #5

      Interesting - looks correct. Where / how do you load the other languages?
      Does https://doc.qt.io/qt-6/qtranslator.html#translate after translator.load() give some useful results?
      The same goes for https://doc.qt.io/qt-6/qcoreapplication.html#translate
      Make sure to pass the correct context when using those functions.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      O 1 Reply Last reply
      0
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Please show how you load them. Especially how long your QTranslator lives.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        O 1 Reply Last reply
        0
        • Paul ColbyP Offline
          Paul ColbyP Offline
          Paul Colby
          wrote on last edited by
          #3

          Hi @oserrabassa,

          What is your operating system / user's locale set to?

          QTranslator::load() only makes the translations for that language available. The actual translations that will get used depend on the current locale. So, for example, say you loaded the translations for English, German and Italian, then: if the user's locale was set to Italian, they would get Italian, but if their locale was set to Spanish, they would get the default untranslated text (since no Spanish translation was loaded). That's slightly simplified, but you get the idea.

          To test your scenario under Linux, for example, you can do something like:

          export LANG=fi_FI.UTF-8
          export LC_ALL=fi_FI.UTF-8
          ./your-app-here
          

          Cheers.

          O 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            Please show how you load them. Especially how long your QTranslator lives.

            O Offline
            O Offline
            oserrabassa
            wrote on last edited by
            #4

            @Christian-Ehrlicher Here are probably the files which you want to check. If you are interested, there is a link to my project in the main post.

            CMakeLists.txt

            cmake_minimum_required(VERSION 3.16)
            
            project(Translations_Section4 VERSION 0.1 LANGUAGES CXX)
            
            set(CMAKE_CXX_STANDARD_REQUIRED ON)
            
            set(APP_NAME "Translations")
            add_compile_definitions(APP_NAME="${APP_NAME}")
            
            find_package(Qt6 6.5 REQUIRED COMPONENTS Quick LinguistTools)
            qt_standard_project_setup(REQUIRES 6.5)
            
            qt_add_executable(
                ${PROJECT_NAME}
                "main.cpp"
                # "cpp/LanguageManager.cpp" "h/LanguageManager.h"
            )
            target_include_directories(
                ${PROJECT_NAME}
                PRIVATE "h/"
            )
            qt_add_qml_module(
                ${PROJECT_NAME}
                URI ${APP_NAME}
                VERSION 1.0
                QML_FILES
                    "Main.qml"
            )
            
            set(
                TRANSLATION_SOURCE_FILES
                "ts/qml_en.ts"
                "ts/qml_fi.ts"
                "ts/qml_fr.ts"
            )
            set(
                QT_MESSAGE_TRANSLATION_FILES_OUTPUT
                "${CMAKE_CURRENT_BINARY_DIR}/qm"
            )
            qt_add_lupdate(
                SOURCE_TARGETS ${PROJECT_NAME}
                TS_FILES ${TRANSLATION_SOURCE_FILES}
            )
            qt_add_lrelease(
                TS_FILES ${TRANSLATION_SOURCE_FILES}
                QM_OUTPUT_DIRECTORY ${QT_MESSAGE_TRANSLATION_FILES_OUTPUT}
                QM_FILES_OUTPUT_VARIABLE QM_FILES
            )
            message(STATUS ".qm files generated at: ${QM_FILES}")
            qt_add_resources(
                ${PROJECT_NAME}
                "translations"
                PREFIX "/qt/qml/${APP_NAME}/i18n"
                BASE ${QT_MESSAGE_TRANSLATION_FILES_OUTPUT}
                FILES ${QM_FILES}
            )
            
            # 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(
                ${PROJECT_NAME} PROPERTIES
                # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.${PROJECT_NAME}
                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(${PROJECT_NAME}
                PRIVATE Qt6::Quick
            )
            
            include(GNUInstallDirs)
            install(
                TARGETS ${PROJECT_NAME}
                BUNDLE DESTINATION .
                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
                RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
            )
            

            main.cpp

            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            #include <QTranslator>
            
            int main(int argc, char *argv[])
            {
                QGuiApplication app(argc, argv);
            
                QTranslator translator;
                if (translator.load(":/qt/qml/Translations/i18n/qml_fi.qm")) {
                    app.installTranslator(&translator);
                    qDebug() << "Finnish translation loaded at startup";
                } else {
                    qWarning() << "Failed to load Finnish translation at startup";
                }
            
                QQmlApplicationEngine engine;
                engine.load(QUrl(QStringLiteral("qrc:/qt/qml/Translations/Main.qml")));
            
                return app.exec();
            }
            

            I tried declaring the QTranslator object outside the main() function and even make the variable static but it does not work.

            1 Reply Last reply
            0
            • Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #5

              Interesting - looks correct. Where / how do you load the other languages?
              Does https://doc.qt.io/qt-6/qtranslator.html#translate after translator.load() give some useful results?
              The same goes for https://doc.qt.io/qt-6/qcoreapplication.html#translate
              Make sure to pass the correct context when using those functions.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              O 1 Reply Last reply
              0
              • Paul ColbyP Paul Colby

                Hi @oserrabassa,

                What is your operating system / user's locale set to?

                QTranslator::load() only makes the translations for that language available. The actual translations that will get used depend on the current locale. So, for example, say you loaded the translations for English, German and Italian, then: if the user's locale was set to Italian, they would get Italian, but if their locale was set to Spanish, they would get the default untranslated text (since no Spanish translation was loaded). That's slightly simplified, but you get the idea.

                To test your scenario under Linux, for example, you can do something like:

                export LANG=fi_FI.UTF-8
                export LC_ALL=fi_FI.UTF-8
                ./your-app-here
                

                Cheers.

                O Offline
                O Offline
                oserrabassa
                wrote on last edited by oserrabassa
                #6

                @Paul-Colby Tried 2 different settings:

                • Changed operating system's (Windows) locale = Application still launches with no initial translation
                • Started application via terminal with the flags you mentioned = Application does indeed start with the specified language
                  • Interestingly enough, I can start the application in any language which has translations. All the QTranslator code seems to be doing nothing? Unfortunately, this is not a solution to my issue because the user is not going to be able to launch the application with these flags
                  • Only the LANG flag seems to matter in my case. The flag LC_ALL does not seem to impact the application in any form.

                I played with these settings a little bit and I found out that the below setup works. Is this reliable?
                main.cpp

                #include <QGuiApplication>
                #include <QQmlApplicationEngine>
                #include <QLocale>
                
                int main(int argc, char *argv[])
                {
                    QGuiApplication app(argc, argv);
                
                    QLocale::setDefault(QLocale::French);
                
                    QQmlApplicationEngine engine;
                    engine.load(QUrl(QStringLiteral("qrc:/qt/qml/Translations/Main.qml")));
                
                    return app.exec();
                }
                

                As you can see, I am simply changing the locale. This should be functional because I could just change the locale to an available language or the last language that the user set in the application.

                What I really do not understand, is how was the Qt Academy tutorial be able to change the language with the QTranslator object while I cannot and I am using the same application. Maybe it is something they changed in newer Qt Framework releases. Although, the approach that I tried is definitely more user-friendly and requires less code.

                1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  Interesting - looks correct. Where / how do you load the other languages?
                  Does https://doc.qt.io/qt-6/qtranslator.html#translate after translator.load() give some useful results?
                  The same goes for https://doc.qt.io/qt-6/qcoreapplication.html#translate
                  Make sure to pass the correct context when using those functions.

                  O Offline
                  O Offline
                  oserrabassa
                  wrote on last edited by
                  #7

                  @Christian-Ehrlicher
                  Where / how do you load the other languages?
                  I only have those 3 languages in the project: English, Finnish, French
                  All are created within CMakeLists.txt under the same resource file.
                  The QTranslator object was just to set a default start/launch/initial language.

                  translate()
                  Translations seems to be working but UI is not getting translated
                  The "Translations" string refers to the window's title.
                  Screenshot 2025-05-27 204734.png

                  1 Reply Last reply
                  0
                  • Paul ColbyP Offline
                    Paul ColbyP Offline
                    Paul Colby
                    wrote on last edited by Paul Colby
                    #8

                    Not sure if this is the issue, but worth trying... I see you're using the non-Locale overload of QTranslator::load(), which specifically says:

                    Usually, it is better to use the QTranslator::load(const QLocale &, const QString &, const QString &, const QString &, const QString &) function instead, because it uses QLocale::uiLanguages() and not simply the locale name, which refers to the formatting of dates and numbers and not necessarily the UI language.

                    So try using the locale-overload: https://doc.qt.io/qt-6/qtranslator.html#load-1

                    For example, here's how I do it in one of my projects:

                        const QLocale locale;
                        QTranslator appTranslator;
                        if (appTranslator.load(locale, u"cli"_s, u"/"_s, u":/i18n"_s)) {
                            QCoreApplication::installTranslator(&appTranslator);
                        }
                    
                        ...
                    
                        qCDebug(lc).noquote() << "Locale:" << locale << locale.uiLanguages();
                    #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) // QTranslator::filePath() added in Qt 5.15.
                        qCDebug(lc).noquote() << "App translations:" <<
                            (appTranslator.filePath().isEmpty() ? u"<none>"_s : appTranslator.filePath());
                    #else
                        qCDebug(lc).noquote() << "App translations:" << (!appTranslator.isEmpty());
                    #endif
                    

                    So try something like:

                        const QLocale locale;
                        qDebug().noquote() << "Locale:" << locale << locale.uiLanguages();
                        QTranslator translator;
                        if (translator.load(locale, ":/qt/....")) {
                            ....
                        }
                    

                    You might also try to calling QmlEngine::retranslate() after the QmlEngine construction?

                    1 Reply Last reply
                    1
                    • O Offline
                      O Offline
                      oserrabassa
                      wrote on last edited by oserrabassa
                      #9

                      Not sure why I am having so many problems in something which looks very straightforward.
                      Nothing really seems to work.
                      failures.png

                      The only time that I have been successful in the User Interface displaying a non-default translation language was with QLocale::setDefault. I believe that I am just going to go and try with this approach. My overall language detection logic in main.cpp is going to be something like:

                      • 0. Check if user has already explicitly set an application language
                        • If that is the case, skip to step 3
                        • This information is going to be stored in an external configuration file outside the application.
                      • 1. Detect user's default locale with QLocale::QLocale()
                      • 2. Check if user's default locale has an available translation in the application
                        • If they do not, either do nothing else, or explicitly change the current locale to match with the default translation language (for the sake of readability)
                        • I need to think exactly how I am going to match the results but QLocale has both QLocale::language() and QLocale::name() and that should be more than enough.
                      • 3. Change default locale to expected locale using QLocale::setDefault

                      I am not planning in adding my languages to my application. So, I am not really worried about having a big switch statement.

                      1 Reply Last reply
                      0
                      • O oserrabassa has marked this topic as solved on

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved