Skip to content

Latest commit

 

History

History
211 lines (128 loc) · 14.6 KB

File metadata and controls

211 lines (128 loc) · 14.6 KB

十、使用 Qt 语言学家本地化您的应用

本地化是当今软件开发中一个重要但通常被忽视的部分。 大多数应用的作者,无论这些应用是商业应用还是开源应用,都希望为他们的应用赢得大量用户。 这意味着越来越多地需要在多个地区支持多种语言,而且通常需要在一个地区支持多种语言(可以将其视为在加拿大共存的法语和英语)。

很长一段时间以来,Qt 都有一个使应用易于本地化的框架,其工具可以帮助您避免在应用中硬编码字符串,还有一个名为Qt Languist的 GUI 来帮助管理翻译。 在本章中,我们将介绍 Qt 的本地化策略,讨论 Qt 提供的三种工具(lupdatelrelease和 Qt Languist)以及如何使用它们,以及在编写应用以利用 Qt 的本地化框架时需要做些什么。

在本章中,我们将介绍以下主题:

  • 理解本地化的任务
  • 标记用于本地化的字符串
  • 使用 QLanguist 本地化您的应用
  • 使用 QLocale 本地化特殊参数-货币和日期

技术要求

本章的技术要求包括 Qt 5.12.3、MinGW 64 位、Qt Creator 4.9.0 和 Windows 10。

理解本地化的任务

如果您想要在全球销售您的产品,本地化是其重要功能。 当用户看到他们的母语在一款软件中被显示和使用时,他们更有可能会依恋它,成为你的忠实客户之一。 然而,本地化并不总是一个容易实现的特性,至少在 Qt 引入了一种更简单的方式之前是这样。

本地化应用有几个阶段,在整个项目生命周期中通常会重叠。

下图显示了这些阶段的交互方式:

这些阶段如下:

  1. 在编写应用时,将需要本地化的字符串放入特定函数中(请参见步骤 5),以便 Qt 可以识别需要本地化的字符串。
  2. 定期提取应用中的所有字符串,并将它们交给翻译人员进行翻译。
  3. 翻译器为应用中的字符串提供翻译。
  4. 您可以使用要支持的每种语言的翻译字符串编译翻译文件。
  5. C++ 和 QML 的trqsTr函数允许您识别应用中需要本地化的字符串。 Qt 提供了四个工具来简化这些阶段。
  6. lupdate命令生成应用中需要本地化的字符串的列表。
  7. 翻译者使用 Qt Languist 为您的应用中的字符串提供翻译。
  8. lrelease命令从 Qt Creator 获取翻译后的字符串,并将它们打包成供您的应用使用的格式。

软件开发是迭代的,本地化也不例外。 小型项目可能更喜欢只本地化一次或两次,等到应用接近完成后再提交应用字符串进行本地化。 大型应用或拥有专职翻译人员的大型公司可能更喜欢迭代的方法,在整个应用开发过程中多次经历本地化周期。 Qt 支持这两种型号。

我们已经了解了本地化的重要性以及如何在 Qt 中实施本地化。 在下一节中,我们将学习如何使用 C++ 方法完成此操作。

标记用于本地化的字符串

回到第 1 章Qt Creator 入门,我告诉过您要始终使用trqsTr函数将字符串标记为本地化:tr用于 C++,qsTr用于 QML 字符串。 这样做有两个关键优势:

  • 它使 Qt 能够找到每个需要本地化的字符串。
  • 如果在应用中安装 Qt Translator 对象并提供翻译文件,则用这些函数包装的字符串将自动替换为它们的本地化等效项。

让我们更详细地研究一下tr的用法。 所有在声明中包含Q_OBJECT宏的 Qt 对象都包含tr函数。 你已经看到了它的一个论点,如下所示:

button = new QPushButton(tr("&Quit"), this); 

字符串中的前导&不是用于tr函数,而是用于键盘快捷键;您可以在字母前面加上&来指定键盘快捷键,它将获得默认系统(对于 Windows,Alt、对于 Apple,cmd和对于 Linux,Alt是一个组合键)。 如果该字符串的翻译版本未出现在应用的当前转换表中,tr函数将使用您在用户界面中作为字符串传递的字符串,或者使用当前转换表中的字符串(如果存在)。

tr函数可以接受第二个参数,即tr用于可能需要不同翻译的同一字符串的消歧上下文。 如下所示:

tr("&Copy", "Menu"); 

此函数还可以处理带复数的字符串,如下所示:

tr("%n item(s) replaced", "", count); 

根据count的值和区域设置,返回不同的字符串。 因此,本地英语翻译可以返回"0 items replaced""1 item replaced""2 items replaced"等,而法语翻译可以返回"0 item remplacé""1 item remplacé""2 items remplacés"等。

在 QML 中,您只需使用qsTr函数,该函数的工作方式与 C++ 中的tr方法完全相同。

在本节中,我们了解了如何标记字符串,让 Qt 知道哪个字符串需要本地化。 接下来,我们将学习如何在 Qt 中运行本地化过程,并根据用户的语言偏好显示正确的语言。

使用 QLanguist 本地化您的应用

一旦使用trqsTr标记了字符串,就需要生成这些字符串的表,以便 Qt 语言学家进行本地化。 可以使用lupdate命令实现这一点,该命令获取.pro文件并遍历源代码以查找要本地化的字符串,并为 Qt 语言学家创建需要翻译的字符串的 XML 文件。 您需要为您想要支持的每种语言执行一次此操作。 在执行此操作时,最好系统地命名生成的文件;一种方法是使用项目文件的名称,后跟破折号,然后是该语言的 ISO-639-2 语言代码。

下面是一个具体的例子。 本章使用QtLinguistExample;我们可以使用如下命令运行lupdate,以创建要转换为世界语(ISO-639-2 语言代码,ePO)的字符串列表:

% lupdate -pro .\QtLinguistExample.pro -ts .\QtLinguistExample-epo.ts

Don't forget that the % character is the Command Prompt, which might differ from system to system.

这里,-pro文件表示.pro文件包含要扫描以查找要翻译的字符串的源列表,而-ts参数表示要写入的翻译文件的名称。 当然,您需要在您的道路上使用lupdate。 如何设置路径将取决于您使用的是 Windows、MacOSX 还是 Linux,以及 Qt 的安装位置。 Qt 的某些安装可能会自动更新您的路径,而其他安装可能不会这样做。 例如,在我的 Windows 机器上,我可以在C:\Qt\5.13.0\msvc2017_64\bin\lupdate.exe处找到lupdate

.ts文件是一个带有标记的 XML 文件,用于指示要翻译的字符串、它们在应用源代码中的上下文等。 Qt 语言学家会将翻译保存到它的输出文件中,该文件的名称也带有一个 QM 后缀,但是不要担心:lupdate足够聪明,如果您在提供一些翻译之后再次运行它,它不会覆盖现有的翻译。

您还可以轻松地从 Qt Creator 运行命令提示符,方法是在项目面板中右键单击.pro命令文件,然后选择 Build Environment(构建环境)选项,以自动配置命令提示符相对于项目目录的路径,如下所示:

除了使用命令外,您还可以直接从 Qt Creator 中使用lupdatelrelease,方法是转到工具|外部|语言学家|更新翻译(Lupdate)或发布翻译(Lrelease)。 请注意,这将更新或释放所有翻译文件。 如果您只想更新或发布特定的文件/语言,命令仍然是您最好的朋友。

以下屏幕截图显示了lupdate工具在应用菜单上的位置:

Qt Language ist 是一个 GUI 应用;在启动该应用时,您将看到一个与下一个屏幕截图非常相似的屏幕:

首先,您需要打开您通过导航到文件|打开文件并选择翻译文件生成的.ts文件。 系统将提示您输入目标语言,然后给出找到的字符串列表:

您或您的翻译人员只需遍历每个字符串,然后以翻译的语言输入相应的字符串。 这样做时,您可以在最右边的窗格中看到源代码中字符串的上下文;从中捕获字符串的源代码所在的行会高亮显示。

Qt 语言学家可以让您跟踪已翻译的字符串以及仍需翻译的字符串。 每个字符串左侧的图标可以是以下图标之一:

  • 黑色问号,表示字符串尚未翻译
  • 黄色问号,表示该字符串没有通过 Qt 语言学家的所有验证测试,但您忽略了这些失败
  • 一个感叹号,表示您提供的字符串没有通过 Qt 语言学家的验证测试
  • 黄色的复选框,表示您提供了翻译,但 Qt Creator 可能发现翻译有问题
  • 绿色的复选框,表示字符串已翻译完毕,可以开始使用了

Qt Languist 提供了一些简单的验证测试,比如确保具有printf样式参数的字符串在每次翻译中都有相同数量的参数。

Qt 语言学家还支持词汇书;您可以下载包含已本地化为目标语言的常用字符串的词汇书。

在任何时候,您都可以通过运行lrelease来生成要包含在应用中的转换文件。 例如,要为世界语字符串创建一个,我们将使用lrelease,如下所示:

% lrelease .\QtLinguistExample-epo.ts .\QtLinguistExample-epo.qm

这将获取传入的.ts文件,并生成包含字符串的.qm文件。 .qm文件是 Qt 在呈现应用的过程中直接使用的高度压缩的二进制文件。

我们已经了解了如何使用 Qt Languist 将所有文本导出到列表中,并允许您和您的翻译人员进行翻译。 接下来,我们将继续在我们的应用中包含本地化文本。

在应用中包含本地化字符串

为了向应用中的trqsTr函数提供翻译后的字符串,您的应用需要包括一个QTranslator对象来读取.qm文件,并将提供给trqsTr的字符串替换为翻译后的对应字符串。

我们可以在您的主要入口点函数中执行此操作,如下所示:

QApplication a(argc, argv); 
QTranslator translator; 
bool result = translator.load("QtLinguistExample-epo.qm"); 
a.installTranslator(&translator); 

    // Other window setup stuff goes here 

return a.exec(); 

此代码分配一个QTranslator对象,并在将其安装到QApplication对象之前将指定的翻译文件加载到转换器中。 在本例中,我们对语言进行了硬编码,以便将其本地化为世界语。

请注意,如果您希望支持系统选择的区域设置,则可以选择这样做:

QString locale = QLocale::system().name(); 
QTranslator translator; 
translator.load(QString("QtLinguistExample-") + locale); 

这里的QLocale类是用于管理系统区域设置的类。 在这里,我们使用它来确定系统的区域设置,然后尝试加载系统当前区域设置的本地化字符串文件。

要实现这一点,应用的.qm文件需要可由应用定位。 它们应该在输出目录中;在开发过程中,一种方法是在 Qt Creator 中关闭影子构建,在项目窗格的 Build 和 Settings 下。 构建应用安装程序是一项特定于平台的任务,这超出了本书的范围,为此,您需要在应用二进制文件中包含.qm个文件。

For more information on Qt Linguist, refer to its manual at https://doc.qt.io/qt-5/qtlinguist-index.html.

接下来,我们将了解如何本地化一些特殊参数以满足我们的要求。

使用 QLocale 本地化特殊参数-货币和日期

您可能需要做的一件常见的事情是本地化货币和日期。 Qt 使这一点变得简单,尽管解决方案在您仔细考虑之前并不明显。 让我们试试看吧。

  1. 您需要了解QString arg方法。 这将用其参数的格式化版本替换转义数字。 例如,如果我们编写以下内容:
QString s = QString("%1 %2").arg("a").arg("b"); 

然后,s将包含字符串"a b"

  1. 您需要了解QLocaletoString方法,该方法以特定于区域设置的方式格式化其参数。 因此,我们可以写下以下内容:
QString currencyValue = QString("%1 %2") 
    .arg(tr("$")).arg(QLocale::toString(value, 'g', 2) 

它使用tr本地化货币符号,并使用QLocale类的静态方法toString将货币值转换为带有区域设置特定小数分隔符(在美国和加拿大为句点,在欧洲为逗号)的字符串。

日期格式类似;QLocaletoString方法重载了QDateTimeQDateQTime参数,因此只需编写以下代码:

QDateTime whenDateTime = QDateTime::currentDateTime(); 
QString when = QLocale::toString(whenDate); 

这将获取当前日期和时间并将其存储在whenDateTime中,然后使用区域设置的默认格式将其转换为字符串。 toString方法可以采用第二个参数来确定输出格式;它是以下参数之一:

  • QLocale::LongFormat:这使用长版本的月份和日期名称。
  • QLocale::ShortFormat:这使用月和日名称的简短版本。
  • QLocale::NarrowFormat:这提供了日期和时间的最窄格式。

就这样。 我们不仅学习了如何使用 Qt 本地化文本,还学习了如何本地化货币和日期等特殊字符。

简略的 / 概括的 / 简易判罪的 / 简易的

使用 Qt 语言学家和 Qt 中的本地化框架,可以轻松地使用 Qt 本地化应用。 不过,要使用该框架,您必须将字符串标记为在源代码中使用trqsTr进行本地化,无论它们出现在哪里。 完成此操作后,您可以使用 Qt 的lupdate命令创建要使用 QLanguist 进行翻译的字符串的源文件,然后为每个字符串提供翻译。 提供翻译后,使用lrelease编译它们,然后通过在应用的主函数中安装QTranslator对象并加载由lrelease生成的翻译表,将它们包含在应用中。

在本章中,我们学习了如何标记可翻译文本,以便 Qt 知道哪些文本需要本地化。 接下来,我们还学习了如何使用 Qt Language ist 将这些文本导出到列表中,以便您和您的翻译人员可以轻松地针对每种语言进行编辑。 然后,我们了解了如何将翻译后的文本重新加载到 Qt 应用中,并根据用户的喜好显示它们。 最后,我们还学习了如何本地化特殊字符,如货币和日期。

在下一章中,我们将介绍 Qt Creator 支持的软件开发的另一个重要方面:使用 QML Profiler 和 Valgrind 进行性能分析。