本地化时钟示例

该示例展示了在 CMake 和Qt Quick 中使用 Qt 的翻译和本地化功能的最佳实践,包括处理不同语言中的复数以及本地化的时间和日期格式。

有关翻译 Qt 应用程序的更多信息,请参阅Qt Linguist Manual

用户界面

该示例以系统语言显示当前时间和日期。此外,用户界面中的文本还针对以下语言进行了本地化:英语、德语、法语、西班牙语、意大利语、日语、韩语、葡萄牙语、阿拉伯语和中文。如果你的桌面使用的是其他语言,它会返回到英语。

为了测试不同的语言和地区而不改变系统,该示例还接受一个地区作为命令行参数。例如,使用--locale de 选项从命令行启动 localizedClock,就会以德语显示时钟,并显示德国常见的日期和时间格式。

截图显示的是 en_US 版本:

国际化

在应用程序中,翻译用于设置主窗口标题和一些用户界面文本,包括带有占位符和复数形式的文本。应用程序在启用复数形式时会计算秒数(请参阅处理复数形式)。因此,根据秒数,翻译功能会返回不同的翻译,并为目标语言提供正确的语法编号。例如,在英语中,如果计数大于1,则使用复数形式,否则使用单数形式。在复数形式的翻译规则中,您可以找到不同语言的复数规则。

地域也会影响日期和时间的显示方式。日期和时间的格式是根据当前地区的国家惯例确定的。例如,德国地区使用 24 小时制,日期写在月份之前,而美国地区使用 12 小时制,月份写在日期之前。

本截图显示的是 en_GB 版本。请注意,数据格式与上述 en_US 版本不同,但两种情况下加载的都是相同的英语复数翻译。

下面是 de_DE 版本的截图,与 GB 相似,它的日期格式也与 US 不同。请注意,常规和复数形式的德语翻译也相应载入。

执行

实现包括三个部分:

CMakeLists.txt

应用程序的 CMake 文件支持 Qt 的翻译和本地化。以下是相关部分:

find_package(Qt6 REQUIRED COMPONENTS Core Linguist Qml Quick):查找并链接所需的 Qt 6 模块,包括对国际化至关重要的Linguist

qt_standard_project_setup(...):I18N_SOURCE_LANGUAGE 保留默认值(英文),因为源代码包含英文文本。

qt_standard_project_setup(REQUIRES 6.8
    I18N_TRANSLATED_LANGUAGES de ar ko zh ja fr it es pt)

qt_add_translations(...):捆绑lupdatelrelease 的功能,在 "i18n "目录下生成翻译源文件(TS 文件),以clock 作为基名,如果包含翻译,则将其编译成二进制.qm 文件。生成的 TS 文件如下

  • "clock_{de、ar、ko、zh、ja、fr、it、es、pt}.ts":I18N_TRANSLATED_LANGUAGES ofqt_standard_project_setup 中列出的每种语言生成一个 TS 文件,其中包含该语言的翻译。
  • "clock_en.ts":包含英文复数形式,因为源代码有复数形式翻译("%n second(s)")。函数qt_add_translations 只在此处写入复数形式,因为我们在源代码中将文本的语言指定为英语,将I18N_SOURCE_LANGUAGE 保留为默认值。因此,复数形式的文本不需要翻译。
qt_add_translations(localizedClock
    TS_FILE_BASE i18n/clock
    RESOURCE_PREFIX i18n
)

qt_add_qml_module(...):在 URIqtexamples.localizedclock 下添加 QML 模块,包括Main.qml文件。

qt_add_qml_module(localizedClock
    URI qtexamples.localizedclock
    VERSION 1.0
    QML_FILES
        Main.qml
)
main.cpp

应用程序的起点。该部分负责设置本地语言、安装所需的翻译和加载用户界面。下面是相关代码的解释:

定义 locale 参数,例如--locale en_US--locale de_DE

    QCommandLineParser parser;
    QCommandLineOption localeOption("locale"_L1, "Locale to be used in the user interface"_L1,
                                    "locale"_L1);
    parser.addOption(localeOption);
    parser.addHelpOption();
    parser.process(app);

解析参数,获取所提供的 locale,并将输入的 locale 设置为应用程序的默认 locale:

        QLocalelocale(parser.value(localeOption));        qInfo() << "Setting locale to" << locale.name();
        QLocale::setDefault(locale);

安装英文翻译,而不考虑本地语言,以允许其他语言的不完整翻译。QTranslator 按照相反的翻译安装顺序查询文本的翻译:

    QTranslatorenPlurals;const autoenPluralsPath= ":/i18n/clock_en.qm"_L1;if(!enPlurals.load(enPluralsPath))        qFatal("Could not load %s!", qUtf8Printable(enPluralsPath));
    app.installTranslator(&enPlurals);

根据给定的本地语言安装翻译。由于英文翻译已在上一步中安装,我们可能会在此处安装两个翻译。Qt 会使用最近安装的翻译来处理任何重叠的键。因此,特定于本地的翻译将优先于英文,如果缺少任何翻译,QTranslator 将返回到英文。

    QTranslator翻译;if(QLocale().language()!=QLocale::English) {if(translation.load(QLocale(), "clock"_L1, "_"_L1, ":/i18n/"_L1)) {            qInfo("Loading translation %s",
                  qUtf8Printable(QDir::toNativeSeparators(translation.filePath())));if(!app.installTranslator(&translation))                qWarning("Could not install %s!",
                         qUtf8Printable(QDir::toNativeSeparators(translation.filePath()))); }else{            qInfo("Could not load translation to %s. Using English.",
                  qUtf8Printable(QLocale().name())); } }
Main.qml

该 QML 文件定义了应用程序的主用户界面窗口,用于显示时间、日期、使用的本地语言和秒计数器。下面是相关代码的解释:

使用 qsTr() 翻译设置窗口标题。要找到该文本的翻译,QTranslator 在当前语言的 TS 文件中查询上下文"Main"(文件名)中的文本"Digital Clock":

title: qsTr("Digital Clock")

使用支持复数(数字)的 qsTr() 显示秒数。复数形式通过使用特殊符号"%n "启用(请参阅 "处理复数形式")。根据 n 的值,翻译函数将返回不同的译文,并为目标语言提供正确的语法数字。例如,在英语中,如果root.seconds 的值大于 1,则使用复数形式,否则使用单数形式。在复数形式的翻译规则中,您可以找到不同语言的复数规则。

text: qsTr("%n second(s)", "seconds", root.seconds)

显示当前语言,并使用 qsTr() 翻译源文本 "Locale: %1"。翻译还需要包含参数符号"%1"。因此,文本的参数(即Qt.locale().name )可以正确地用于格式化文本:

text: qsTr("Locale: %1").arg(Qt.locale().name)

根据本地约定格式化时间和日期。不同国家可能对时间和日期的显示方式有特定的偏好。例如,德国地区使用 24 小时时钟,并将日写在月之前,而美国地区则使用 12 小时时钟,并将月放在日之前。Date.toLocaleTimeString 方法会考虑这些因素,并根据给定的本地语言正确格式化时间和日期:

            const now = new Date();
            const locale = Qt.locale();
            root.time = now.toLocaleTimeString(locale, Locale.ShortFormat);
            root.date = now.toLocaleDateString(locale);

示例项目 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.