Международная локализация и локализация с 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. Разъяснение идентичных текстов
Система перевода объединяет строки пользовательского интерфейса в уникальные элементы. Это объединение экономит время переводчика, так как ему не нужно переводить один и тот же текст несколько раз. Однако в некоторых случаях текст идентичен, но имеет разное значение. Например, в английском языке «назад» означает шаг назад, а также часть объекта, противоположную фронту. Вам необходимо сообщить системе перевода о этих двух разных значениях, чтобы переводчик мог создать два отдельных перевода.
Различайте идентичные тексты, добавив некоторый идентификатор в качестве второго параметра функции 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. Использование %x для вставки параметров в строку
Разные языки располагают слова в разном порядке, поэтому не стоит создавать предложения, конкатенируя слова и данные. Вместо этого используйте % для вставки параметров в строки. Например, следующий фрагмент содержит строку с двумя числовыми параметрами %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 Linguist для получения более подробной информации о локализации Qt.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/qtquick-internationalization.html