Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Runtime translation / i18n - QML C++ engine
QtWS25 Last Chance

Runtime translation / i18n - QML C++ engine

Scheduled Pinned Locked Moved Solved QML and Qt Quick
i18ntranslationqml c++ enginenestedlanguagechange
2 Posts 1 Posters 2.0k Views
  • 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.
  • M Offline
    M Offline
    Marco Pellin
    wrote on 31 May 2017, 10:01 last edited by Marco Pellin
    #1

    Hi there,

    I'm new in here, and it's about a couple of months I'm using Qt.

    What I'm doing now is playing with dynamic translation in QML.
    I started with those references:
    How to do dynamic translation in QML
    Dynamic translations for mobile apps at runtime?

    The instructions worked, in fact I'm able to change language at runtime.
    But...it doesn't apply to items defined in external qml files and included into the main qml.
    I guess I'm missing something related to C++ and QML linking.

    Here the code I'm using:


    translationtest.h

    #ifndef TRANSLATIONTEST_H
    #define TRANSLATIONTEST_H
    
    #include <QObject>
    #include <QTranslator>
    
    class TranslationTest : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString emptyString READ getEmptyString NOTIFY languageChanged)
    public:
        explicit TranslationTest(QObject *parent = 0);
        QString getEmptyString();
        Q_INVOKABLE void selectLanguage(QString language);
    
        QTranslator * translator;
    
    signals:
        void languageChanged();
    
    private:
    
    };
    
    #endif // TRANSLATIONTEST_H
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QQmlComponent>
    
    #include "translationtest.h"
    
    TranslationTest::TranslationTest(QObject *parent) : QObject(parent) {
        translator = new QTranslator(this);
        translator->load(QLocale(QLocale::English), QLatin1String("provaTranslate"), QLatin1String("_"), QLatin1String(":/translations"));
    }
    
    QString TranslationTest::getEmptyString() {
        return "";
    }
    
    void TranslationTest::selectLanguage(QString language) {
        if(language == QString("it")) {
            qApp->removeTranslator(translator);
            translator->load(QLocale(QLocale::Italian), QLatin1String("provaTranslate"), QLatin1String("_"), QLatin1String(":/translations"));
            qApp->installTranslator(translator);
        }
    
        if(language == QString("de")) {
            qApp->removeTranslator(translator);
            translator->load(QLocale(QLocale::German), QLatin1String("provaTranslate"), QLatin1String("_"), QLatin1String(":/translations"));
            qApp->installTranslator(translator);
        }
    
        if(language == QString("en")) {
            qApp->removeTranslator(translator);
            translator->load(QLocale(QLocale::English), QLatin1String("provaTranslate"), QLatin1String("_"), QLatin1String(":/translations"));
            qApp->installTranslator(translator);
        }
    
        emit languageChanged();
    }
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        /*! Dynamic translation */
        TranslationTest translator;
        app.installTranslator(translator.translator);
    
        QQmlApplicationEngine engine;
        QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
        engine.rootContext()->setContextProperty("rootItem",&translator);
        component.create();
    
        return app.exec();
    }
    

    So, with those files "main.qml" is aware of "rootItem" context, which will in fact be linked to the TranslatorTest class.


    Now, that's my main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World") + rootItem.emptyString
    
        SwipeView {
            id: swipeView
            anchors.fill: parent
            currentIndex: tabBar.currentIndex
    
            Page1 {
            }
    
            Page {
                Label {
                    text: qsTr("Second page") + rootItem.emptyString
                    anchors.centerIn: parent
                }
            }
        }
    
        footer: TabBar {
            id: tabBar
            currentIndex: swipeView.currentIndex
            TabButton {
                text: qsTr("First") + rootItem.emptyString
            }
            TabButton {
                text: qsTr("Second") + rootItem.emptyString
            }
        }
    }
    

    The text contained here is successfully changing while choosing another language.
    But the "Page1" item, extenally defined, is not showing the same behaviour. It is simply not changing at all.


    Here my Page1.qml file (extending "Page1Form.ui.qml" functionalities)

    import QtQuick 2.7
    
    Page1Form {
        button1 {
            text: qsTr("Press Me") + rootItem.emptyString
            onClicked: console.log("Button Pressed. Entered text: " + textField1.text)
        }
    
        textField1.placeholderText: qsTr("Text Field") + rootItem.emptyString
    
        label {
            text: "Test: " + Number(23.7).toLocaleString(Qt.locale()) + " °C" + rootItem.emptyString
        }
    
        italiano.onClicked: {
            rootItem.selectLanguage("it")
        }
    
        deutsch.onClicked: {
            rootItem.selectLanguage("de")
        }
    
        english.onClicked: {
            rootItem.selectLanguage("en")
        }
    }
    

    So the C++ "selectLanguage" function is actually called even from "Page1.qml", while it's not receiving any updates given by "emptyString". Everything of "Page1" will be displayed as it's written into the code, even if the first language loaded into the constructor is e.g. "Italian".

    Do you know how to fix this?

    Thank you very much, even just for reading the whole story!

    1 Reply Last reply
    0
    • M Offline
      M Offline
      Marco Pellin
      wrote on 30 Jun 2017, 07:32 last edited by
      #2

      In the end everything was fine with the example above.
      I just had to update and release my translation files, because in the meantime I changed the name of a .qml file, and the filename is directly linked into the .ts files created by linguist and used by Qt.
      I feel a bit ashamed but yes, it was really trivial and kinda stupid :)

      1 Reply Last reply
      2

      • Login

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