Локализация и интернационализация с 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. Используйте Locale для расширения функций локализации
Если вы хотите использовать разные графические или звуковые элементы для разных географических регионов, вы можете использовать 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.13/qtquick-internationalization.html