Spec-Zone.ru › Qt 5.14

Локализация и интернационализация с Qt Quick

Локализация вашего приложения

В следующих разделах описаны различные аспекты локализации вашего кода QML. Если вы следуете этим рекомендациям для всех компонентов пользовательского интерфейса вашего приложения, то становится возможной локализация всех аспектов вашего приложения для различных языков и локальных культурных соглашений, таких как форматирование дат и чисел.

1. Использование qsTr() для всех текстовых строк пользовательского интерфейса

Строки в QML могут быть помечены для перевода с помощью функций qsTr(), qsTranslate(), qsTrId(), QT_TR_NOOP(), QT_TRANSLATE_NOOP(), и QT_TRID_NOOP(). Наиболее распространённым способом маркировки строк является функция qsTr(). Например:

Text {
    id: txt1;
    text: qsTr("Back");
}

Этот код делает "Назад" ключевым элементом в файлах перевода. Во время выполнения система перевода ищет ключевое слово "Назад" и получает соответствующее значение перевода для текущей локали системы. Результат возвращается к свойству text и пользовательский интерфейс отобразит соответствующий перевод "Назад" для текущей локали.

2. Добавление контекста для переводчика

Строки пользовательского интерфейса часто короткие, поэтому вам необходимо помочь переводчику понять контекст текста. Вы можете добавить контекстную информацию в исходный код в виде дополнительного описательного текста перед строкой, подлежащей переводу. Эти дополнительные описания включаются в файлы перевода .ts, предоставляемые переводчику.

Примечание: Файлы .ts являются XML-файлами с исходными текстами и местом для переведённого текста. Обновлённые файлы .ts преобразуются в двоичные файлы перевода и включаются в состав конечного приложения.

В следующем фрагменте кода текст на строке //: является основным комментарием для переводчика.

Текст на строке //~ — это необязательная дополнительная информация. Первое слово текста используется в качестве дополнительного идентификатора в XML-элементе в файле .ts, поэтому убедитесь, что первое слово не является частью предложения. Например, комментарий "Контекст не связан с этим" преобразуется в "<extra-Context>Не связан с этим" в файле .ts.

Text {
    id: txt1;
    // This user interface string is only used here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back");
}

3. Различение идентичных текстов

Система перевода объединяет текстовые строки пользовательского интерфейса в уникальные элементы. Это объединение экономит время переводчика, так как ему не нужно переводить один и тот же текст несколько раз. Однако в некоторых случаях текст идентичен, но имеет разное значение. Например, в английском языке "back" означает "назад" (шаг назад) и "спинка" (часть объекта, противоположная передней части). Вам нужно сообщить системе перевода об этих двух различных значениях, чтобы переводчик мог создать два отдельных перевода.

Различайте идентичные тексты, добавив некоторый идентификатор в качестве второго параметра функции qsTr().

В следующем фрагменте кода текст not front — это идентификатор для различения этого текста "Назад" от текста "назад" в значении шага назад:

Text {
    id: txt1;
    // This user interface string is used only here
    //: The back of the object, not the front
    //~ Context Not related to back-stepping
    text: qsTr("Back", "not front");
}

4. Использование %1, %2… для вставки параметров в строку

Разные языки располагают слова в предложениях по-разному, поэтому не следует создавать предложения путём конкатенации слов и данных. Вместо этого используйте %1, %2… для вставки параметров в строки. Например, следующий фрагмент содержит строку с двумя числовыми параметрами %1 и %2 . Эти параметры вставляются с помощью функций .arg().

Text {
    text: qsTr("File %1 of %2").arg(counter).arg(total)
}

%1 относится к первому параметру, а %2 относится ко второму параметру, поэтому этот код генерирует вывод типа: "Файл 2 из 3".

5. Использование %Lx для локализации чисел

Если вы включите модификатор %L при указании параметра, число будет локализовано в соответствии с текущими региональными настройками. Например, в следующем фрагменте кода %L1 означает форматирование первого параметра в соответствии с правилами форматирования чисел текущей выбранной локали (географического региона):

Text {
    text: qsTr("%L1").arg(total)
}

Затем, с приведенным выше кодом, если total — это число "4321.56" (четыре тысячи триста двадцать один целых пятьдесят шесть сотых); с английскими региональными настройками (локаль) вывод составляет "4,321.56"; с немецкими региональными настройками вывод составляет "4.321,56".

6. Локализация дат, времён и валют

Нет специальных модификаторов строк для форматирования дат и времени. Вместо этого необходимо запросить текущую локаль (географический регион) и использовать методы класса Date для форматирования строки.

Qt.locale() возвращает объект Locale, содержащий всю информацию о локали. В частности, свойство Locale.name содержит информацию о языке и стране для текущей локали. Вы можете использовать значение как есть или обработать его для определения соответствующего содержимого для текущей локали.

Следующий фрагмент получает текущую дату и время с помощью Date(), затем преобразует её в строку для текущей локали. Затем вставляет строку даты в параметр %1 для соответствующего перевода.

Text {
    text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}

Для локализации числовых значений валют используйте тип Number. Этот тип имеет аналогичные функции, как тип Date для преобразования чисел в локализованные строки валют.

7. Использование QT_TR_NOOP() для переводимых строк данных

Если пользователь меняет язык системы без перезагрузки, в зависимости от системы, строки в массивах, списках моделей и других структурах данных могут не обновляться автоматически. Чтобы принудительно обновить тексты при их отображении в пользовательском интерфейсе, необходимо объявить строки с помощью макроса QT_TR_NOOP(). Затем при заполнении объектов для отображения необходимо явно извлечь перевод для каждого текста. Например:

ListModel {
    id: myListModel;
    ListElement {
        //: Capital city of Finland
        name: QT_TR_NOOP("Helsinki");
        }
    }

...

Text {
    text: qsTr(myListModel.get(0).name); // get the translation of the name property in element 0
    }

8. Использование локали для расширения возможностей локализации

Если вам нужны разные графические изображения или аудио для разных географических регионов, вы можете использовать Qt.locale() для получения текущей локали. Затем вы выбираете соответствующие графические изображения или аудио для этой локали.

Следующий фрагмент кода показывает, как можно выбрать подходящий значок, представляющий язык текущей локали.

Component.onCompleted: {
    switch (Qt.locale().name.substring(0,2)) {
        case "en":   // show the English-language icon
            languageIcon = "../images/language-icon_en.png";
            break;
        case "fi":   // show the Finnish language icon
            languageIcon = "../images/language-icon_fi.png";
            break;
        default:     // show a default language icon
            languageIcon = "../images/language-icon_default.png";
    }
}

9. Подготовка к динамическим изменениям языка

Вы можете изменить язык, используемый функциями перевода Qt, добавив и удалив переводчиков с помощью QCoreApplication::installTranslator() и QCoreApplication::removeTranslator(). После этого вы можете вызвать QQmlEngine::retranslate() для запуска обновления всех связей, использующих переводы. В результате ваш пользовательский интерфейс будет динамически переключаться на выбранный язык.

В качестве альтернативы, вы также можете передать событие QEvent::LanguageChange в экземпляр QQmlEngine вашего приложения или подключить собственный сигнал к QQmlEngine::retranslate().

Локализация вашего приложения

Приложения Qt Quick используют ту же базовую систему локализации, что и приложения Qt C++ (lupdate, lrelease и файлы .ts). Вы используете те же инструменты, что описаны в Руководстве Qt Linguist. Вы даже можете иметь строки пользовательского интерфейса в C++ и QML-источнике в одном приложении. Система создаст один объединённый файл перевода, и строки будут доступны из QML и C++.

Используйте условную конструкцию для скрытия QML-источника от компилятора

Инструмент lupdate извлекает строки пользовательского интерфейса из вашего приложения. lupdate считывает файл .pro вашего приложения, чтобы определить, какие исходные файлы содержат тексты, подлежащие переводу. Это означает, что ваши исходные файлы должны быть указаны в записи SOURCES или HEADERS в файле .pro. Если ваши файлы не указаны, тексты в них не будут найдены.

Однако переменная SOURCES предназначена для файлов исходного кода C++. Если вы указываете QML или JavaScript файлы исходного кода, компилятор пытается скомпилировать их как C++ файлы. В качестве обходного решения вы можете использовать lupdate_only{...} условную конструкцию, чтобы инструмент lupdate видел файлы .qml, а C++ компилятор их игнорировал.

Например, фрагмент файла .pro ниже указывает два файла .qml в приложении.

lupdate_only{
SOURCES = main.qml \
          MainPage.qml
}

Вы также можете указать файлы .qml исходного кода с использованием шаблона. Поиск не рекурсивный, поэтому вам нужно указать каждую директорию, где есть строки пользовательского интерфейса в исходном коде:

lupdate_only{
SOURCES = *.qml \
          *.js \
          content/*.qml \
          content/*.js
}

Дополнительные сведения о локализации Qt см. в Руководстве Qt Linguist.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.14/qtquick-internationalization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API