Evgenii Legotckoi
Evgenii Legotckoi5. Juni 2016 12:43

QML - Lektion 025. Dynamische Übersetzung einer mehrsprachigen Anwendung auf QML

Nachdem wir uns mit Übersetzungen der Anwendungsschnittstelle zu Qt/C++ vertraut gemacht haben, ist es an der Zeit, die Möglichkeiten der dynamischen Übersetzung einer Anwendung zu erkunden, deren Schnittstelle geschrieben ist in * QML. *

Bei der Entwicklung auf QML sind im Gegensatz zu einer Standardanwendung auf QWidgets einige Dinge zu beachten, nämlich:

  1. Eine zusätzliche Konfiguration der .pro-Projektdatei ist erforderlich;
  2. Der Prozess des Ladens von Übersetzungen für die gewünschte Sprache wird in der C++-Schicht durchgeführt;
  3. Die Schnittstellenübersetzung wird in der QML -Schicht mit der Funktion qsTr(); neu initialisiert
  4. Nach dem Laden der Übersetzung müssen Sie ein Signal von der C++-Schicht an die QML -Schicht senden, um die Anwendungsschnittstelle erneut zu übersetzen, was für die C++-Anwendung ähnlich ist, aber die Einrichtung der Interaktion von C++ erfordert Ebene mit der Ebene QML .

Projektstruktur

Erstellen Sie ein Projekt, das die folgenden Dateien enthält:

  • QmlLanguage.pro - Projektprofil;
  • deployment.pri - Bereitstellungseinstellungsdatei, standardmäßig erstellt;
  • main.cpp - Quellcodedatei mit main-Funktion;
  • qmltranslator.h - Header-Datei der Übersetzungsladeklasse;
  • qmltranslator.cpp - Quellcodedatei der Übersetzungsladeklasse;
  • main.qml - QML -Hauptdatei der Ebene.

QmlLanguage.pro

Das Erstellen einer Übersetzungsdatei ähnelt dem Erstellen von Übersetzungen für eine Qt/C++-Anwendung. Das heißt, Sie müssen eine Übersetzungsdatei einfügen, mit der Qt Linguist arbeitet:

# Добавляем файл переводов,
# который является по сути файлом "исходных кодов" для нашего перевода
TRANSLATIONS += QmlLanguage_ru.ts

Als Nächstes führen wir das Dienstprogramm lupdate aus, um diese Übersetzungsdatei zu erstellen, bearbeiten sie in Qt Linguist und führen das Dienstprogramm lrelease aus, um eine binäre Übersetzungsdatei zu erstellen, die in die Anwendung aufgenommen wird.

Sie können mehr darüber im vorherigen Artikel über die Verwendung von QTranslator lesen.

Der wichtigste Punkt für die Arbeit mit Übersetzungen in QML ist, dass Sie alle QML-Dateien als Quellen einschließen müssen, genau wie normale C++-Dateien. Aber mit einer Markierung, die nur für die Verwendung lupdate_only.

lupdate_only {
    SOURCES += main.qml
}

Nachfolgend finden Sie die vollständige Auflistung der .pro-Datei des Projekts.

TEMPLATE = app

QT += qml quick widgets

CONFIG += c++11

SOURCES += main.cpp \
    qmltranslator.cpp

# Для того, чтобы создать файл переводов со строками из ресурсов qml
# понадобится включить файл qml в качестве обычных исходников в pro файле
# но только для использования утилиты lupdate, чтобы она могла узнать,
# какие строки нуждаются в переводе
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)

# Добавляем файл переводов,
# который является по сути файлом "исходных кодов" для нашего перевода
TRANSLATIONS += QmlLanguage_ru.ts

HEADERS += \
    qmltranslator.h

main.cpp

Da Übersetzungsdateien in der C++-Schicht enthalten sind, müssen Sie ein Übersetzungsklassenobjekt im QML-Kontext registrieren. In diesem Fall schreiben wir die QmlTranslator -Klasse, die ein Wrapper für QTranslator ist , da diese Klasse keine Methoden hat, mit denen wir durch QML. arbeiten könnten.

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

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

    // Создаём объект для работы с переводами ...
    QmlTranslator qmlTranslator;

    QQmlApplicationEngine engine;
    // и регистрируем его в качестве контекста в Qml слое
    engine.rootContext()->setContextProperty("qmlTranslator", &qmlTranslator);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

qmltranslator.h

Die Klasse hat eine Methode zum Setzen der Übersetzung, der das Präfix der Zielsprache übergeben wird. Und von dieser Methode wird ein Signal zum Ändern der Übersetzung ausgegeben, sodass es möglich ist, die gesamte Schnittstelle mit einer neuen Übersetzung erneut zu übersetzen.

Die Übersetzungsaufbaumethode muss mit dem Makro Q_INVOKABLE, gekennzeichnet werden, damit sie in der QML -Schicht verwendet werden kann.

#ifndef QMLTRANSLATOR_H
#define QMLTRANSLATOR_H

#include <QObject>
#include <QTranslator>

class QmlTranslator : public QObject
{
    Q_OBJECT

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

signals:
    // Сигнал об изменении текущего языка для изменения перевода интерфейса
    void languageChanged();

public:
    // Метод установки перевода, который будет доступен в 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, "."); // Загружаем перевод
    qApp->installTranslator(&m_translator);                 // Устанавливаем его в приложение
    emit languageChanged();                                 // Сигнализируем об изменении текущего перевода
}

main.qml

Die Anwendungsoberfläche sieht folgendermaßen aus:

Die Anwendungslogik ist wie folgt: Beim Ändern der Sprache in der Combobox ändert sich die Anwendungssprache.

Da wir qmlTranslator im Kontext der QML -Schicht registriert haben, rufen wir im Textänderungshandler in der Combobox die Sprachänderungsmethode im qmlTranslator-Objekt auf. Und um die Sprachänderung zu verfolgen signalisieren, müssen Sie sich mit diesem über das Signal vom Typ Connections verbinden und einen Handler schreiben, in dem die Funktion retranslateUi() aufgerufen wird. Die Funktion retranslateUi() enthält alle Texteigenschaften aller Objekte, die übersetzt werden müssen. Dies wurde getan, um die Logik zu vereinfachen und redundanten Code zu reduzieren.

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"]

        // При изменении текста, инициализируем установку перевода через С++ слой
        onCurrentTextChanged: {
            qmlTranslator.setTranslation(comboBox.currentText)
        }
    }

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

    // Подключаемся к объекту переводчика
    Connections {
        target: qmlTranslator   // был зарегистрирован в main.cpp
        onLanguageChanged: {    // при получении сигнала изменения языка
            retranslateUi()     // инициализируем перевод интерфейса
        }
    }

    // Функция перевода интерфейса
    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.")
    }

    // Запускаем перевод приложения, когда окно приложения было создано
    Component.onCompleted: {
        retranslateUi();
    }
}

Insgesamt

Im Allgemeinen unterscheidet sich die dynamische Übersetzung einer Anwendung in Qt/QML nicht wesentlich von der Übersetzung einer Anwendung, die nur Qt/C++ verwendet. Der Schlüssel liegt darin, die Signale und Slots korrekt zu verbinden und die Methoden korrekt aufzurufen, um die Übersetzung zu initialisieren.

QML-Anwendung mit dynamischer Übersetzung herunterladen

Videoanleitung

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

ДЧ
  • 31. Januar 2019 05:25
  • (bearbeitet)

Всё отлично :)
Только у меня вопрос: а как вместо 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
  • 15. Juli 2019 05:32

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

Evgenii Legotckoi
  • 15. Juli 2019 05:35

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

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 14:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 18:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr9. Februar 2024 02:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 18:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 10:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 22:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 16:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 11:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken