Evgenii Legotckoi
Evgenii LegotckoiJune 5, 2016, 12:43 p.m.

QML - Lesson 025. Dynamic translation of multilanguage application on QML

Once we have learn how to make the translation of the application interface at Qt/C++ , it is time to research possibilities of dynamic translation application interface which is written in QML.

In developing the QML to have a couple of moments that need to be taken into account, as opposed to the standard application on QWidgets, namely:

  1. Requires additional configuration .pro file;
  2. Process of the loading of translation for your language is carried in C ++ layer;
  3. Reinitialize the translation interface implemented in QML layer using qsTr() function;
  4. After loading the translation, you need to send a signal from the C ++ layer in QML layer to re-translate the application interface.

Project Structure

Create a project, which will include the following files:

  • QmlLanguage.pro - profile of project;
  • deployment.pri - configuration file of deployment, created by default;
  • main.cpp - source file of file with main function;
  • qmltranslator.h - header file of class for translation loading;
  • qmltranslator.cpp - sourcefile of class for translation loading;
  • main.qml - main file of QML layer.

QmlLanguage.pro

Creating a translation file will be similar to how it is done when creating a translation for Qt / C ++ applications. That is, you need to connect the translation file. We will work with this file useing Qt Linguist:

# Add the translation file
# Which is in fact the file "source code" for our translation
TRANSLATIONS += QmlLanguage_ru.ts

Then run the utility lupdate, to create the translation file, edit it in the Qt Linguist, and launch lrelease create a binary translation file, which will be connected to the application.

Read more about this in a previous article on the use of QTranslator .

The most important thing to work with translations in QML is what you need to connect all the QML file as the source, as ordinary C ++ files. But with a mark that only use lupdate_only.

lupdate_only {
    SOURCES += main.qml
}

Below is the complete listing of the project .pro file.

TEMPLATE = app

QT += qml quick widgets

CONFIG += c++11

SOURCES += main.cpp \
    qmltranslator.cpp

# To create a translation file with strings of resources qml<br># need to include qml file as normal source in the .pro file<br># But only for use lupdate utility, so that she could learn,<br># Which strings need to be translated
lupdate_only {
    SOURCES += main.qml
}

RESOURCES += qml.qrc \
    translations.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)

# Add the translation file
# Which is in fact the file "source code" for our translation
TRANSLATIONS += QmlLanguage_ru.ts

HEADERS += \
    qmltranslator.h

main.cpp

Because of connection of the translation file is carried in C ++ layer, you will need to register the class object in QML context. In this case, we will write QmlTranslator class that is a wrapper over QTranslator, because the class has no methods with which we could work through QML.

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "qmltranslator.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    // Create an object to work with translations ...
    QmlTranslator qmlTranslator;

    QQmlApplicationEngine engine;
    // and register it as a context in Qml layer
    engine.rootContext()->setContextProperty("qmlTranslator", &qmlTranslator);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

qmltranslator.h

In the class there is  method for the translation loading, in which we will pass the target language prefix. And from this method will emit a signal of the translation change to be able to re-translate the interface with a new translation.

Translation installation method you have to mark macro Q_INVOKABLE, to be able to use it in QML layer.

#ifndef QMLTRANSLATOR_H
#define QMLTRANSLATOR_H

#include <QObject>
#include <QTranslator>

class QmlTranslator : public QObject
{
    Q_OBJECT

public:
    explicit QmlTranslator(QObject *parent = 0);

signals:
    // The signal of change the current language to change the interface translation
    void languageChanged();

public:
    // Translation installation method, which will be available in QML
    Q_INVOKABLE void setTranslation(QString translation);

private:
    QTranslator m_translator;
};

#endif // QMLTRANSLATOR_H

qmltranslator.cpp

#include "qmltranslator.h"
#include <QApplication>

QmlTranslator::QmlTranslator(QObject *parent) : QObject(parent)
{

}

void QmlTranslator::setTranslation(QString translation)
{
    m_translator.load(":/QmlLanguage_" + translation, "."); // load translation
    qApp->installTranslator(&m_translator);                 // Set it to the application
    emit languageChanged();                                 // Signaling a change in the current translation
}

main.qml

Application interface will appear as follows:

The application logic is as follows: when you change the language in the combo box will change the language of the application.

Since we registered qmlTranslator in the context of QML layer, the change in the output text in the combo box will cause a change of language in the object method qmlTranslator. And in order to keep track of changes in the language signal, you must use type Connections to connect to this signal and write a handler which will be called retranslateUi(). The function retranslateUi() rendered all the text properties of all the objects that need to be subjected to transfer. This is to simplify the logic and reduce redundancy.

import QtQuick 2.6
import QtQuick.Controls 1.5

ApplicationWindow {
    id: applicationWindow
    visible: true
    width: 640
    height: 480

    Label {
        id: helloLabel
        height: 50
        anchors {
            top: parent.top
            left: parent.left
            right: parent.horizontalCenter
            margins: 10
        }
    }

    ComboBox {
        id: comboBox
        anchors {
            top: parent.top
            left: parent.horizontalCenter
            right: parent.right
            margins: 10
        }

        model: ["ru_RU", "en_US"]

        // If you change the text, initialize the translation unit via C++ Layer
        onCurrentTextChanged: {
            qmlTranslator.setTranslation(comboBox.currentText)
        }
    }

    Label {
        id: labelText
        wrapMode: Text.Wrap
        anchors {
            top: helloLabel.bottom
            left: parent.left
            right: parent.right
            margins: 10
        }
    }

    // Connect to an interpreter object
    Connections {
        target: qmlTranslator   // was registered in main.cpp
        onLanguageChanged: {    // upon receipt of the signal to change the language
            retranslateUi()     // initialize interface translation
        }
    }

    // interface translation function
    function retranslateUi() {
        applicationWindow.title = qsTr("Hello World")
        helloLabel.text = qsTr("Hello World")
        labelText.text = qsTr("The QTranslator class provides internationalization" +
                              "support for text output.An object of this class contains " +
                              "a set of translations from a source language to a target language. " +
                              "QTranslator provides functions to look up translations in a translation file. " +
                              "Translation files are created using Qt Linguist.")
    }

    // Start translating the application window when the application was created
    Component.onCompleted: {
        retranslateUi();
    }
}

Result

In general, the dynamic translation application on Qt/QML is not much different from the translation application using only Qt/C ++. The key point is that you need to properly connect the signals and slots, and the right to call methods for the transfer initialization.

Download QML application with dynamic translation

Video

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

ДЧ
  • Jan. 31, 2019, 5:25 a.m.
  • (edited)

Всё отлично :)
Только у меня вопрос: а как вместо ru_RU и en_US написать в ComboBox'e Russian и English чтобы сохранить функцию смены языка :)

UPD Разобрался
В comboBox model я пишу так:

model: ["English", "Russian"]

И перед отправкой кода ru_RU или en_US в С++ делаю проверку

onCurrentTextChanged: {
            if(comboBox.currentText === "Russian")
                qmlTranslator.setTranslation("ru_RU")
            if(comboBox.currentText === "English")
                qmlTranslator.setTranslation("en_US")
        }
zloi
  • July 15, 2019, 5:32 a.m.

В Qt 5.10 была добавлена новая функция по переводу qml файлов. Теперь не нужно писать класс оболочку, достаточно вызвать функцию engine.retranslate(); и все обновится само.

Evgenii Legotckoi
  • July 15, 2019, 5:35 a.m.

Это хорошая новость!!!!

Comments

Only authorized users can post comments.
Please, Log in or Sign up
AD

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
ИМ
Игорь МаксимовNov. 22, 2024, 7:51 p.m.
Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiOct. 31, 2024, 9:37 p.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 3:19 p.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 2:51 p.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 6:02 p.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 24, 2024, 10:11 p.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 2:04 p.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 10:49 a.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 4:10 p.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks