Локализация и интернационализация с 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-6.0/qtquick-internationalization.html