使用 Qt Quick 进行国际化和本地化

一、国际化应用程序

以下部分描述了国际化 QML 源代码的各个方面。如果应用程序中的所有用户界面组件都遵循这些指南,则可以针对不同的语言和当地文化习俗(例如日期和数字的格式化方式)本地化应用程序的各个方面。

1.1、对所有文字用户界面字符串使用 qsTr()

QML 中的字符串可以使用 qsTr()、qsTranslate()、qsTrId()、QT_TR_NOOP()、QT_TRANSLATE_NOOP() 和 QT_TRID_NOOP() 函数标记为翻译。标记字符串的最常用方法是使用 qsTr() 函数。例如:

Text 
{
    id: txt1;
    text: qsTr("Back");
}

此代码使“Back”成为翻译文件中的关键条目。在运行时,翻译系统查找关键字“Back”,然后获取当前系统语言环境对应的翻译值。结果返回到 text 属性,用户界面将显示当前语言环境的“Back”的适当翻译。

1.2、为翻译器添加上下文

用户界面字符串通常很短,因此需要帮助翻译文本的人理解文本的上下文。可以在源代码中添加上下文信息作为要翻译的字符串的额外描述性文本。这些额外的描述包含在交付给翻译人员的 .ts 翻译文件中。

.ts 文件是带有源文本和翻译文本位置的 XML 文件。.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");
}

在上面代码片段中:

  • //: 行上的文本是翻译器的主要注释。
  • //~ 行上的文本是可选的额外信息。文本的第一个单词用作 .ts 文件中 XML 元素的附加标识符,因此请确保第一个单词不是句子的一部分。例如,.ts 文件中的注释“Context Not related to that”被转换为“<extra-Context>Not related to that”。

1.3、消除相同文本的歧义

翻译系统将用户界面文本字符串合并为独特的项目。这种合并使翻译工作的人员不必多次翻译相同的文本。 但是,在某些情况下,文本相同但含义不同。 

通过添加一些 id 文本作为 qsTr() 函数的第二个参数来区分相同的文本。

在以下代码片段中,not front 文本是一个 id,用于区分此“Back”文本与后退“Back”文本:

Text 
{
    id: txt1;
    text: qsTr("Back", "not front");
}

1.4、使用 %x 将参数插入字符串

下面的代码片段有一个带有两个数字参数 %1 和 %2 的字符串。这些参数与 .arg() 函数一起插入。

Text 
{
    text: qsTr("File %1 of %2").arg(counter).arg(total)
}

%1 指的是第一个参数,%2 指的是第二个参数,此代码产生的输出类似于:“File 2 of 3”。

1.5、使用 %Lx 使数字本地化

如果在指定参数时包含 %L 修饰符,则数字将根据当前选择的语言环境(地理区域)的数字格式约定来格式化。

Text 
{
    text: qsTr("%L1").arg(total)
}

如果 total 是数字“4321.56”,英文区域设置输出为“4,321.56”;德文区域设置输出为“4.321,56”。

1.6、国际化日期、时间和货币

需要查询当前的语言环境(地理区域)并使用 Date 的方法来格式化字符串。

Qt.locale() 返回一个 Locale 对象,其中包含有关语言环境的各种信息。特别是,Locale.name 属性包含当前语言环境的语言和国家信息。可以对其进行解析以确定当前语言环境的适当内容。

Text 
{
    text: qsTr("Date %1").arg(Date().toLocaleString(Qt.locale()))
}

上面代码段使用 Date() 获取当前日期和时间,然后将其转换为当前语言环境的字符串。 然后它将日期字符串插入到 %1 参数中以进行适当的转换。

要确保货币数字已本地化,请使用 Number 类型。 此类型具有与 Date 类型类似的功能,用于将数字转换为本地化的货币字符串。

1.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); // 获取元素 0 中 name 属性的翻译
}

1.8、使用 Locale 扩展本地化功能

如果想要不同地理区域的不同图形或音频,可以使用 Qt.locale() 来获取当前的语言环境。 然后为该语言环境选择合适的图形或音频。

下面的代码片段展示了如何选择一个合适的图标来代表当前语言环境的语言。

Component.onCompleted: 
{
    switch (Qt.locale().name.substring(0,2)) 
    {
        case "en": 
            languageIcon = "../images/language-icon_en.png";
            break;
        case "fi": 
            languageIcon = "../images/language-icon_fi.png";
            break;
        default: 
            languageIcon = "../images/language-icon_default.png";
    }
}

1.9、为动态语言变化做好准备

可以通过使用 QCoreApplication::installTranslator() 和 QCoreApplication::removeTranslator() 添加和删除翻译器来更改 Qt 翻译函数使用的语言。之后可以调用 QQmlEngine::retranslate() 来触发所有使用翻译的绑定的刷新。因此,用户界面将动态切换到新选择的语言。

或者,也可以将 QEvent::LanguageChange 事件转发到应用程序的 QQmlEngine 实例或将自己的信号连接到 QQmlEngine::retranslate()。

二、本地化应用程序

Qt Quick 应用程序使用与 Qt C++ 应用程序相同的底层本地化系统(lupdate、lrelease 和 .ts 文件)。

.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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值