QT多语言
应用程序的国际化和本地化是将应用程序适应不同语言、地区差异和目标市场技术要求的过程。国际化是指设计一个软件应用,使其可以在不进行工程修改的情况下适应各种语言和地区。 本地化是指通过添加特定区域或语言的组件(如日期、时间和数字格式)并翻译文本来使国际化的软件适应特定地区或语言。
相关的 Qt 类和 API
这些类支持 Qt 应用程序的国际化。
类名 | 描述 |
---|---|
QCollator | 根据本地化的排序算法比较字符串 |
QCollatorSortKey | 可用于加速字符串排序 |
QLocale | 在各种语言中转换数字及其字符串表示 |
QTextCodec | 文本编码之间的转换 |
QTextDecoder | 基于状态的解码器 |
QTextEncoder | 基于状态的编码器 |
QTranslator | 支持文本输出的国际化 |
语言和书写系统
在某些情况下,国际化是比较简单的,例如,使美国的应用程序对澳大利亚或英国用户可访问,可能只需要进行一些拼写更正。但要使美国的应用程序适用于日本用户,或者使韩国的应用程序适用于德国用户,则不仅需要软件能够在不同的语言中操作,还需要使用不同的输入技术、字符编码和显示规范。
Qt 尽量让开发人员的国际化工作变得尽可能简单。Qt 中的所有输入控件和文本绘制方法都内置支持所有支持的语言。内置的字体引擎能够正确且美观地渲染包含来自各种不同书写系统的字符的文本。
Qt 支持当今使用的大多数语言,特别是:
- 所有东亚语言(中文、日文和韩文)
- 所有西方语言(使用拉丁字母)
- 阿拉伯语
- 斯拉夫语(俄语、乌克兰语等)
- 希腊语
- 希伯来语
- 泰语和老挝语
- Unicode 6.2 中所有不需要特殊处理的书写系统
- 孟加拉语
- 缅甸语(缅甸)
- 天城文
- 古吉拉特语
- 果鲁穆奇语
- 卡纳达语
- 高棉语
- 马拉雅拉姆语
- 泰米尔语
- 泰卢固语
- 藏语
上述语言在所有平台上都得到支持,只要系统安装了渲染这些书写系统的字体。
在 Windows、Linux 和 Unix 平台上使用 FontConfig(客户端字体支持),还支持以下语言:
- 迪维希语(塔那字母)
- 叙利亚语
- N’Ko 语
在 macOS 上,还支持以下语言:
- 奥里亚语
- 僧伽罗语
许多这些书写系统具有特殊特征:
- 特殊的换行行为。 一些亚洲语言的书写没有单词之间的空格。换行可以发生在每个字符之后(有例外),如中文、日文和韩文,或在逻辑单词边界之后,如泰语。
- 双向书写。 阿拉伯语和希伯来语从右到左书写,除了数字和嵌入的英语文本是从左到右书写的。确切的行为在 Unicode 技术附件 #9 中定义。
- 非间隔或变音符号(欧洲语言中的重音或变音符)。 一些语言如越南语广泛使用这些符号,一些字符可以同时有多个符号以明确发音。
- 连字。 在特定上下文中,一些字符对被替换为一个组合的连字。常见的例子是排版美国和欧洲书籍时使用的 fl 和 fi 连字。
Qt 尽力处理上述所有特殊特征。只要使用 Qt 的输入控件(例如 QLineEdit、QTextEdit 和派生类或 Quick TextInput 项目)和 Qt 的显示控件(例如 QLabel 和 Qt Quick 的 Text 项目),你通常不必担心这些特征。
对程序员来说,这些书写系统的支持是透明的,并完全封装在 Qt 的文本引擎中。这意味着除非你想编写自己的文本输入控件,否则通常不需要了解特定语言使用的书写系统。在某些语言中,例如阿拉伯语或印度次大陆的语言,字形的宽度和形状会根据周围的字符而变化。要考虑到这一点,请使用 QTextLayout。编写输入控件还需要了解它们将要使用的书写系统。通常,最简单的方法是子类化 QLineEdit 或 QTextEdit。
有关如何国际化源代码的更多信息,请参见《编写用于翻译的源代码》和《使用 Qt Quick 进行国际化和本地化》。
生成翻译
Qt 为将 Qt C++ 和 Qt Quick 应用程序翻译成本地语言提供了出色的支持。发布经理、翻译人员和开发人员可以使用 Qt 的翻译工具完成他们的任务。
Qt 翻译工具包括 Qt Linguist、lupdate
和 lrelease
,这些工具安装在 Qt 基础目录的 bin
子目录中。有关使用它们的更多信息,请参见 Qt Linguist 手册。
Qt 本身包含数千个字符串,这些字符串也需要翻译成您所针对的语言。您将在 qttranslations 仓库中找到许多翻译文件。在开始翻译 Qt 之前,请阅读维基页面《将 Qt 翻译成其他语言》。
启用翻译
通常,您的应用程序的 main()
函数如下所示:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTranslator myappTranslator;
myappTranslator.load(QLocale(), QLatin1String("myapp"), QLatin1String("_"), QLatin1String(":/i18n"));
app.installTranslator(&myappTranslator);
return app.exec();
}
对于支持翻译的应用程序,创建一个QTranslator对象,然后根据用户的首选 UI 显示区域设置在运行时加载翻译,最后将翻译对象安装到应用程序中。
定位 Qt 翻译文件
您还可以使用 QLibraryInfo::location() 来定位所使用的 Qt 模块的翻译文件。通过将 QLibraryInfo::TranslationsPath 传递给该函数,您可以在运行时请求翻译文件的路径。
可用的翻译目录
Qt 的翻译目录位于 qttranslations
仓库中。
警告: Qt 翻译由 Qt 社区贡献,并不提供任何保证。翻译可能缺失、过时或完全错误,甚至可能是恶意的。建议您审核任何发布的翻译。
qt_
元目录包含了在 Qt 4 中包含的仍然存在的 Qt 翻译。它的创建是为了使应用程序从 Qt 4 向 Qt 5 迁移更容易。元目录依赖的翻译可能会缺失,因为它们属于不必要或已弃用的模块,这可能会导致翻译加载失败。如果您的应用程序中使用了 Qt 5 中的新模块,即使使用元目录,也必须指定这些模块的目录名称。
以下表格列出了 Qt 模块和工具的可用翻译目录。
Qt 模块或工具 | 目录 |
---|---|
Qt Assistant | assistant_ |
Qt Bluetooth | qtconnectivity_ |
Qt Concurrent | qtbase_ |
Qt Core | qtbase_ |
Qt D-Bus | qtbase_ |
Qt Designer | designer_ |
Qt GUI | qtbase_ |
Qt Help | qt_help_ |
Qt Linguist | linguist_ |
Qt Location | qtlocation_ |
Qt Multimedia | qtmultimedia_ |
Qt Multimedia Widgets | qtmultimedia_ |
Qt NFC | qtconnectivity_ |
Qt Network | qtbase_ |
Qt Positioning | qtlocation_ |
Qt Print Support | qtbase_ |
Qt QML | qtdeclarative_ |
Qt Quick | qtdeclarative_ |
Qt Quick Controls | qtquickcontrols2_ |
Qt Quick Widgets | qtdeclarative_ |
Qt Serial Port | qtserialport_ |
Qt SQL | qtbase_ |
Qt WebEngine | qtwebengine_ |
Qt WebSockets | qtwebsockets_ |
Qt Widgets | qtbase_ |
示例:基本的 Qt 模块
例如,要定位基本的 Qt 模块(如 Qt Core、Qt GUI、Qt Network 和 Qt Widgets)的翻译,可以在 main()
函数中添加以下代码:
QTranslator qtTranslator;
qtTranslator.load(QLocale::system(), QStringLiteral("qtbase_"));
app.installTranslator(&qtTranslator);
编码支持
QTextCodec
类以及 QTextStream
中的功能使得支持用户数据的许多旧版输入和输出编码变得简单。当应用程序启动时,机器的区域设置将确定处理外部 8 位数据时使用的 8 位编码。QTextCodec::codecForLocale()
返回一个编解码器,可用于在此区域设置编码和 Unicode 之间进行转换。
应用程序可能偶尔需要除默认本地 8 位编码之外的其他编码。例如,位于 Cyrillic KOI8-R 区域设置(俄罗斯的事实上的标准区域设置)的应用程序可能需要以 ISO 8859-5 编码输出 Cyrillic。代码示例如下:
QString string = ...; // 一些 Unicode 文本
QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
QByteArray encodedString = codec->fromUnicode(string);
用于将 Unicode 转换为本地 8 位编码的便捷方式是:QString::toLocal8Bit()
函数返回这样的 8 位数据。另一个有用的快捷方式是 QString::toUtf8()
,它返回以 8 位 UTF-8 编码的文本:这样做可以完美地保留 Unicode 信息,同时如果文本完全是 ASCII,则看起来像是纯 ASCII。
用于反向转换的方法有 QString::fromUtf8()
和 QString::fromLocal8Bit()
便捷函数,或者使用通用代码,如从 ISO 8859-5 Cyrillic 转换为 Unicode 的示例:
QByteArray encodedString = ...; // 一些以 ISO 8859-5 编码的文本
QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
QString string = codec->toUnicode(encodedString);
应该使用 Unicode I/O,因为这样可以最大程度地提高文档在世界各地用户之间的可移植性。然而,在许多情况下,仍然需要支持其他编码,因为用户需要处理现有文档。要支持的最重要的附加编码是由 QTextCodec::codecForLocale()
返回的编码,因为这是用户最有可能需要与其他人和应用程序进行通信的编码(这是 local8Bit()
使用的编解码器)。
Qt 本地支持大多数经常使用的编码。有关受支持编码的完整列表,请参阅 QTextCodec 文档。
在某些情况下,对于不太常用的编码,可能需要编写自己的 QTextCodec
子类。取决于紧急程度,联系 Qt 的技术支持团队或在 qt-interest
邮件列表上询问是否有其他人正在努力支持该编码可能是有用的。
本地化数字、日期、时间和货币
本地化是根据当地惯例进行调整的过程,例如使用当地首选的格式呈现日期和时间。对于本地化的数字、日期、时间和货币字符串,请使用 QLocale 类。
不建议对图像进行本地化。选择清晰的图标,适用于所有地区,而不是依赖于地方谐音或扭曲的隐喻。唯一的例外是左右箭头的图像,在阿拉伯语和希伯来语环境中可能需要反转。
动态翻译
某些应用程序,例如 Qt Linguist,在运行时必须能够支持用户语言设置的更改。为了使部件能够感知到已安装的 QTranslator 对象的更改,请重新实现部件的 changeEvent() 函数以检查事件是否为 LanguageChange 事件,并使用常规方法更新部件显示的文本,使用 tr() 函数。例如:
void MyWidget::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange) {
titleLabel->setText(tr("Document Title"));
...
okPushButton->setText(tr("&OK"));
} else
QWidget::changeEvent(event);
}
应通过调用该函数的默认实现传递所有其他更改事件。
已安装的翻译器列表可能会因为 LocaleChange 事件而发生变化,或者应用程序可能提供了一个用户界面,允许用户更改当前应用程序语言。
QWidget 子类的默认事件处理程序会响应 LanguageChange 事件,并在必要时调用此函数。
当使用 QCoreApplication::installTranslator() 函数安装新的翻译时,将发布 LanguageChange 事件。此外,其他应用程序组件也可以通过将 LanguageChange 事件发布给它们来强制部件更新自己。
系统支持
Qt 运行的一些操作系统和窗口系统对 Unicode 的支持有限。底层系统中可用的支持水平在一定程度上影响了 Qt 在这些平台上提供的支持,尽管一般来说,Qt 应用程序不需要过分关注特定平台的限制。
Unix/X11
- 基于地区的字体和输入法。Qt将这些隐藏起来,并提供Unicode输入和输出。
- 大多数Unix变体默认使用UTF-8等文件系统约定。所有Qt文件函数都允许Unicode,但将文件名转换为本地8位编码,因为这是Unix的约定(参见QFile::setEncodingFunction()以探索替代编码)。
- 文件I/O默认为本地8位编码,QTextStream中提供Unicode选项。
- 一些较旧的Unix发行版只包含对某些区域设置的部分支持。例如,如果您有一个
/usr/share/locale/ja_JP.EUC
目录,这并不一定意味着您可以显示日文文本;您还需要安装日文字体,并且/usr/share/locale/ja_JP.EUC
目录需要完整。为获得最佳结果,请使用来自您系统供应商的完整区域设置。
Linux
- Qt提供完整的Unicode支持,包括输入法、字体、剪贴板和拖放。
- 在所有现代Linux发行版上,文件系统通常以UTF-8编码,不应该存在问题。文件I/O默认为UTF-8。
Windows
- Qt提供完整的Unicode支持,包括输入法、字体、剪贴板、拖放和文件名。
- 文件I/O默认为Latin1,在QTextStream中提供Unicode选项。请注意,尽管大端Unicode文本文件是Unicode标准在缺乏更高级别协议时规定的顺序,但一些Windows程序可能无法理解这种文件。
macOS
有关macOS特定翻译的详细信息,请参阅此处的Qt for macOS问题文档。
相关页面
概述翻译流程 | |
---|---|
Qt Linguist 示例 | 使用Qt Linguist国际化您的Qt应用程序 |
Qt Linguist 手册 | |
Qt Linguist 手册:开发人员 | |
Qt Linguist 手册:发布管理 | |
Qt Linguist 手册:TS 文件格式 | |
Qt Linguist 手册:基于文本 ID 的翻译 | 基于文本ID的国际化为具有许多目标区域设置和许多要翻译的文本的大型项目提供支持 |
Qt Linguist 手册:翻译者 | |
复数形式的翻译规则 | Qt的国际化工具产生的复数形式翻译规则摘要。 |
为翻译编写源代码 | 如何编写源代码,使用户可见文本可以被翻译。 |