国际化您的应用程序
以下部分描述了国际化QML源代码的各个方面。如果您对应用程序中的所有用户界面组件都遵循这些指南,则可以针对不同语言和本地文化约定(例如日期和数字的格式化方式)本地化应用程序的各个方面。
1.对所有Literal用户界面字符串使用qsTr()
可以使用qsTr(),qsTranslate(),qsTrId(),QT_TR_NOOP(),QT_TRANSLATE_NOOP()和QT_TRID_NOOP()函数标记QML中的字符串进行转换。标记字符串的最常用方法是使用qsTr()函数。例如:
Text {
id: txt1;
text: qsTr("Back")
}
此代码使“Back”成为翻译文件中的关键条目。在运行时,翻译系统会查找关键字“Back”,然后获取当前系统区域设置的相应翻译值。结果返回到text
属性,用户界面将显示当前语言环境的“Back”的相应转换。
2.为翻译器添加上下文
用户界面字符串通常很短,因此您需要帮助翻译文本的人理解文本的上下文。您可以在要翻译的字符串之前将源代码中的上下文信息添加为额外的描述性文本。这些额外的描述包含在提供给翻译者的.ts翻译文件中。
注意: .ts文件是包含源文本的XML文件和翻译文本的位置。更新的.ts文件将转换为二进制转换文件,并作为最终应用程序的一部分包含在内。
在以下代码段中,该//:
行上的文本是翻译者的主要注释。
该//~
行上的文字是可选的额外信息。文本的第一个单词用作.ts文件中XML元素的附加标识符,因此请确保第一个单词不是句子的一部分。例如,注释“Context not related that that”将转换为.ts文件中的“<extra-Context>与此无关”。
lupdate_only{
SOURCES = *.qml \
*.js \
content/*.qml \
content/*.js
}
3.消除相同文本的歧义
翻译系统将用户界面文本字符串合并为唯一项。这种合并可以节省翻译工作的人必须多次翻译相同的文本。但是,在某些情况下,文本相同但含义不同。例如,在英语中,“后退”表示向后退一步,也表示与前面相对的物体部分。您需要告诉翻译系统这两个单独的含义,以便翻译人员可以创建两个单独的翻译。
通过添加一些id文本作为qsTr()函数的第二个参数来区分相同的文本。
在下面的代码片段中,not front
文本是一个id,用于区分“Back”文本和backstepping“Back”文本:
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");
}
4.用于%x
将参数插入字符串
不同的语言将单词放在不同的顺序中,因此通过连接单词和数据来创建句子不是一个好主意。相反,用于%
将参数插入字符串。例如,下面的片段具有两个数参数的字符串%1
和%2
。这些参数随.arg()
函数一起插入。
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");
}
%1引用第一个参数并%2
引用第二个参数,因此该代码生成如下输出:“File 2 of 3”。
5.使用%Lx使数字本地化
如果%L
在指定参数时包含修改器,则会根据当前区域设置对数字进行本地化。例如,在以下代码段中,%L1
表示根据当前所选语言环境(地理区域)的数字格式约定格式化第一个参数:
Text {
text: qsTr("File %1 of %2").arg(counter).arg(total)
}
然后,用上面的代码,如果total
是数字“4321.56”(四千三百二十一点五十六); 使用英文区域设置,(区域设置)输出为“4,321.56”; 使用德国区域设置,输出为“4.321,56”。
6.国际化日期,时间和货币
没有用于格式化日期和时间的特殊字符串修饰符。相反,您需要查询当前区域设置(地理区域)并使用Date方法格式化字符串。
Qt.locale()
返回一个Locale对象,其中包含有关语言环境的各种信息。特别是,Locale.name属性包含当前语言环境的语言和国家/地区信息。您可以按原样使用该值,也可以对其进行解析以确定当前区域设置的相应内容。
以下代码段使用Date()获取当前日期和时间,然后将其转换为当前语言环境的字符串。然后,它将日期字符串插入%1参数以进行适当的转换。
Text {
text: qsTr("%L1").arg(total)
}
要确保货币号已本地化,请使用数字类型。此类型具有与日期类型类似的功能,用于将数字转换为本地化货币字符串。
7.对可翻译数据文本字符串使用QT_TR_NOOP()
如果用户在不重新启动的情况下更改系统语言,则系统可能无法自动刷新阵列和列表模型中的字符串以及其他数据结构。要在用户界面中显示文本时强制刷新文本,您需要使用QT_TR_NOOP()宏声明字符串。然后,当您填充要显示的对象时,您需要显式检索每个文本的翻译。例如:
Text {
text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}
8.使用区域设置扩展本地化功能
如果您想要不同地理区域的不同图形或音频,可以使用Qt。locale()获取当前的语言环境。然后为该区域设置选择合适的图形或音频。
以下代码段显示了如何选择代表当前语言环境语言的相应图标。
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
}
9.准备动态语言更改
您可以通过使用QCoreApplication :: installTranslator()和QCoreApplication :: removeTranslator()添加和删除转换器来更改Qt转换函数使用的语言。之后,您可以调用QQmlEngine :: retranslate()来触发刷新所有使用翻译的绑定。因此,您的用户界面将动态切换到新选择的语言。
或者,您也可以将QEvent :: LanguageChange事件转发到应用程序的QQmlEngine实例,或将您自己的信号连接到QQmlEngine :: retranslate()。
本地化您的应用程序
Qt Quick应用程序使用与Qt C ++应用程序相同的底层本地化系统(lupdate,lrelease和.ts文件)。您使用Qt语言学手册中描述的相同工具。您甚至可以在同一个应用程序中使用C ++和QML源中的用户界面字符串。系统将创建单个组合翻译文件,并且可以从QML和C ++访问字符串。
使用条件隐藏编译器中的QML源
该lupdate
工具从应用程序中提取用户界面字符串。lupdate读取应用程序的.pro文件,以识别哪些源文件包含要翻译的文本。这意味着您的源文件必须列在.pro文件的SOURCES
或HEADERS
条目中。如果未列出您的文件,则无法找到其中的文本。
但是,SOURCES变量适用于C ++源文件。如果在那里列出QML或JavaScript源文件,编译器会尝试将它们构建为C ++文件。作为一种变通方法,您可以使用lupdate_only{...}
条件语句,以便lupdate
工具查看.qml文件,但C ++编译器会忽略它们。
例如,以下.pro文件片段指定应用程序中的两个.qml文件。
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";
}
}
您还可以使用通配符匹配指定.qml源文件。搜索不是递归的,因此您需要指定源代码中存在用户界面字符串的每个目录:
lupdate_only{
SOURCES = main.qml \
MainPage.qml
}
有关Qt本地化的更多详细信息,请参阅Qt语言学手册。