Международная и локальная локализация с 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-Контекст>Не относится к этому» в файле .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. Используйте %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 см. в Руководстве по Qt Linguist.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.12/qtquick-internationalization.html