概述
Qt使用Unicode编码可显示的文本字符串。Unicode为世界上所有常用的书写系统提供支持,是跨平台开发的理想选择。还可以使用Qt强大的国际化系统,用一个代码库编写应用程序来支持任意数量的不同语言。
Qt中的Unicode
Unicode是世界上几乎所有语言文本编码的标准。如今,在大多数现代操作系统中,它被用作文本的原生编码。主要的例外是Microsoft Windows,它仍然有一个双重系统,支持应用程序的代码页和Unicode。
Qt字符串相关的类
这些类在处理字符串数据时是相关的。有关呈现文本的信息,请参阅富文本处理概述,如果字符串数据是XML格式,请参阅XML处理概述。
| QByteArray | Array of bytes |
| QByteArrayList | List of byte arrays |
| QByteArrayMatcher | Holds a sequence of bytes that can be quickly matched in a byte array |
| QChar | 16-bit Unicode character |
| QCollator | Compares strings according to a localized collation algorithm(根据本地化排序算法比较字符串) |
| QCollatorSortKey | Can be used to speed up string collation |
| QLatin1Char | 8-bit ASCII/Latin-1 character |
| QLatin1String | Thin wrapper around an US-ASCII/Latin-1 encoded string literal |
| QLocale | Converts between numbers and their string representations in various languages(在不同语言中的数字及其字符串表示形式之间进行转换) |
| QStaticByteArrayMatcher | Compile-time version of QByteArrayMatcher |
| QString | Unicode character string |
| QStringList | List of strings |
| QStringMatcher | Holds a sequence of characters that can be quickly matched in a Unicode string |
| QStringRef | Thin wrapper around QString substrings |
| QStringView | Unified view on UTF-16 strings with a read-only subset of the QString API |
| QTextBoundaryFinder | Way of finding Unicode text boundaries in a string |
| QTextStream | Convenient interface for reading and writing text |
Web上关于Unicode的信息
Unicode Consortium有许多可用的文档:
- The current version of the standard
- A technical introduction to Unicode
- The home page for the standard
Qt中的Unicode
在Qt和大多数使用Qt的应用程序中,大多数或所有用户可见的字符串都是使用Unicode存储的。Qt提供:
- 文件I/O的传统编码转换:参见QTextCodec和QTextStream。
- 支持特定于语言环境的输入法和键盘。
- 一个字符串类,QString,存储Unicode字符,支持从C字符串迁移,包括快速转换到UTF-8、ISO8859-1和US-ASCII,以及所有常见的字符串操作。
- 支持unicode的UI控件。
- 兼容Unicode的文本分割(QTextBoundaryFinder)
- Unicode兼容的断行和文本呈现
为了充分利用Unicode,我们建议使用QString存储所有用户可见的字符串,并使用QTextStream执行所有文本文件I/O。
Qt中的所有函数参数可能是用户可见的字符串,QLabel::setText()和许多其他参数,采用const QString &s。QString提供了const char *的隐式强制转换。
label->setText("Password:");
为了有效工作。还有一个函数,QObject::tr(),提供翻译支持,如下所示:
label->setText(tr("Password:"));
QObject::tr()将const char *映射为Unicode字符串,并使用可安装的QTranslator对象进行映射。
Qt提供了许多内置的QTextCodec类,也就是说,这些类知道如何在Unicode和遗留编码之间进行转换,以支持必须与其他程序通信或以遗留文件格式读写文件的程序。
const char *与const char *之间的转换使用UTF-8。但是,应用程序可以很容易地找到其他地区的编解码器,并将任何打开的文件或网络连接设置为使用特殊的编解码器。
由于US-ASCII和ISO-8859-1是如此普遍,也有特别快速的函数映射他们的函数。例如,要打开一个应用程序的图标,可以这样做:
QFile file(QString::fromLatin1("appicon.png"));
QFile file(QLatin1String("appicon.png"));
Qt支持呈现世界上大多数语言的文本。支持的书写系统的详细列表在一定程度上取决于目标系统上的操作系统支持和字体可用性。
Qt国际化
应用程序的国际化和本地化是使应用程序适应目标市场的不同语言、区域差异和技术要求的过程。国际化意味着设计软件应用程序,使其能够适应各种语言和地区,而无需进行工程更改。本地化意味着通过添加特定于区域设置的组件(如日期、时间和数字格式)和翻译文本,使国际化的软件适应特定的区域或语言。
相关的Qt类和api
这些类支持Qt应用程序的国际化。
| QCollator | Compares strings according to a localized collation algorithm |
| QCollatorSortKey | Can be used to speed up string collation |
| QLocale | Converts between numbers and their string representations in various languages |
| QTextCodec | Conversions between text encodings |
| QTextDecoder | State-based decoder |
| QTextEncoder | State-based encoder |
| QTranslator | Internationalization support for text output |
语言和文字系统
在某些情况下,国际化很简单,例如,使澳大利亚或英国用户可以访问美国应用程序可能只需要进行一些拼写更正。但是,要让日本用户可以使用美国应用程序,或者让德国用户可以使用韩国应用程序,不仅需要这些软件以不同的语言运行,还需要使用不同的输入技术、字符编码和表示惯例。
Qt试图使国际化对开发人员来说尽可能轻松。Qt中的所有输入控件和文本绘制方法都为所有支持的语言提供内置支持。内置的字体引擎能够正确而美观地呈现同时包含各种不同书写系统字符的文本。
Qt支持目前使用的大多数语言,特别是:
- 所有东亚语言(中文、日文及韩文)
- 所有西方语言(使用拉丁文字)
- 阿拉伯语
- 西里尔语言(俄语、乌克兰语等)
- 希腊
- 希伯来语
- 泰国和老挝
- Unicode 6.2中不需要特殊处理的所有脚本
- 孟加拉语
- 缅甸(缅甸)
- 梵文字母
- 古吉拉特语
- 果鲁穆奇语
- 埃纳德语
- 高棉语
- 马拉雅拉姆语
- 泰米尔
- 泰卢固语
- 藏文
上面的列表是受支持的,只要系统安装了渲染这些书写系统的字体,就可以在所有平台上工作。
在Windows, Linux和Unix上使用FontConfig(客户端字体支持)也支持以下语言:
- 迪维希(Thaana)
- 叙利亚的
- N 'Ko
在macOS上,还支持以下语言:
- 奥里萨邦
- 僧伽罗语
这些书写系统中有许多表现出特殊的特点:
- 特殊的断行行为。有些亚洲语言的书写没有空格。断行既可以发生在每个字符之后(有例外),如中文、日文和韩文,也可以发生在逻辑词边界之后,如泰文。
- 双向写作。阿拉伯语和希伯来语是从右向左书写的,除了数字和嵌入的英语文本是从左向右书写的。确切的行为定义在Unicode Technical Annex #9中。
- 非空格或变音符号(欧洲语言中的重音或变音符)。一些语言,如越南语,广泛使用这些标记,有些字符可以同时有多个标记来澄清发音。
- Ligatures绑扎。在特殊的上下文中,一些字符对会被一个组合的字形取代,从而形成一个连词。常见的例子是美国和欧洲书籍排版中使用的fl和fi字形。
Qt尝试照顾到上面列出的所有特殊功能。你通常不需要担心这些功能,只要你使用Qt的输入控件(如QLineEdit, QTextEdit,和派生类或快速文本输入项)和Qt的显示控件(如QLabel和Qt快速文本项)。
对这些书写系统的支持对程序员来说是透明的,并且完全封装在Qt的文本引擎中。这意味着您通常不需要了解特定语言中使用的书写系统,除非您想编写自己的文本输入控件。在一些语言中,如阿拉伯语或印度次大陆的语言,字形的宽度和形状取决于周围的字符。要考虑到这一点,请使用QTextLayout。编写输入控件还需要对将要使用它们的脚本有一定的了解。通常,最简单的方法是创建QLineEdit或QTextEdit的子类。
有关如何国际化源代码的更多信息,请参阅 Writing Source Code for Translation and Internationalization and Localization with Qt Quick.。
产品翻译
Qt为将Qt c++和Qt Quick应用程序翻译成本地语言提供了出色的支持。发布经理、翻译人员和开发人员可以使用Qt翻译工具来完成他们的任务。
Qt翻译工具,比如Qt Linguist、lupdate和lrelease安装在Qt安装的基本目录的bin子目录中。有关使用它们的更多信息,请参阅Qt语言学家手册。
Qt本身包含数千个字符串,这些字符串也需要被翻译成目标语言。您将在qttranslations存储库中找到许多翻译文件。在开始翻译Qt之前,请阅读wiki页面将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显示语言环境加载翻译,最后将translator对象安装到应用程序中
查找Qt翻译
您还可以使用QLibraryInfo::location()来查找所使用的Qt模块的翻译。您可以在运行时通过将QLibraryInfo::TranslationsPath传递给该函数来请求翻译的路径。
可用的目录
Qt翻译目录位于qttranslations存储库中。
警告:Qt翻译是由Qt社区贡献的,没有任何保证。翻译可能是缺失的、过时的或完全不正确的,甚至达到恶意的程度。建议您审核您发布的任何翻译。
qt_ meta目录包含了Qt 4中qt_ meta目录中仍然存在的Qt翻译。它的创建是为了更容易地将应用程序从Qt 4移植到Qt 5。元目录依赖于可能不存在的翻译,因为它们属于不必要的或已弃用的模块,这可能导致翻译加载失败。如果在应用程序中使用Qt 5中的新模块,即使使用元目录,也必须指定这些模块的目录名称。
下表列出了Qt模块和Qt中的工具可用的翻译目录。
| Qt Module or Tool | Catalog |
|---|---|
| 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_ |
例如:Basic Qt Modules
例如,要定位基本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 = ...; // some Unicode text
QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
QByteArray encodedString = codec->fromUnicode(string);
要将Unicode转换为本地8位编码,有一个快捷方式:QString::toLocal8Bit()函数返回这样的8位数据。另一个有用的快捷方式是QString::toUtf8(),它返回8位UTF-8编码的文本:这种方式可以像所有文本都是ASCII一样完美地保留Unicode信息
对于另一种方式的转换,有QString::fromUtf8()和QString::fromLocal8Bit()方便函数,或者通用代码,由ISO 8859-5西里尔字母到Unicode的转换演示:
QByteArray encodedString = ...; // some ISO 8859-5 encoded text
QTextCodec *codec = QTextCodec::codecForName("ISO 8859-5");
QString string = codec->toUnicode(encodedString);
应该使用Unicode I/O,因为这可以最大限度地提高世界各地用户之间文档的可移植性。但是,在许多情况下,仍然需要支持其他编码,因为您的用户将需要处理现有文档。要支持的最重要的附加编码是QTextCodec::codecForLocale()返回的编码,因为这是用户最有可能需要与其他人和应用程序通信的编码(这是local8Bit()使用的编解码器)。
Qt原生支持大多数更常用的编码。有关支持编码的完整列表,请参阅QTextCodec文档。
在某些情况下,对于不太常用的编码,可能需要编写自己的QTextCodec子类。根据紧急情况,联系Qt的技术支持团队或询问Qt兴趣邮件列表,看看是否有人已经在支持编码,这可能是有用的。
本地化数字、日期、时间和货币
本地化是适应当地惯例的过程,例如使用当地首选的格式显示日期和时间。对于本地化的数字、日期、时间和货币字符串,使用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子类的默认事件处理程序响应QEvent::LanguageChange事件,并在必要时调用该函数。
当使用QCoreApplication::installTranslator()函数安装新的翻译时,LanguageChange事件被发布。此外,其他应用程序组件也可以通过向小部件发布LanguageChange事件来强制小部件更新自己。
系统支持
Qt所运行的某些操作系统和窗口系统对Unicode的支持有限。底层系统的支持程度对Qt在这些平台上提供的支持有一定的影响,尽管在一般情况下Qt应用程序不需要太关注特定于平台的限制。
Unix / X11
- 面向环境的字体和输入法。Qt隐藏了这些,并提供了Unicode输入和输出。
- 像UTF-8这样的文件系统约定在大多数Unix变体中都是默认使用的。所有Qt文件函数都允许Unicode,但会将文件名转换为本地的8位编码,因为这是Unix的惯例(请参阅QFile::setEncodingFunction()来探索其他编码)。
- 文件I/O默认使用本地8位编码,在QTextStream中使用Unicode选项。
- 一些较旧的Unix发行版只包含对某些地区的部分支持。例如,如果你有一个/usr/share/local / ja_jp .在EUC目录下,这并不一定意味着可以显示日文文本;你还需要安装日文字体,以及/usr/share/local / ja_jp .需要完成EUC目录。为获得最佳效果,请使用系统供应商提供的完整区域设置。
Linux
Qt提供了完整的Unicode支持,包括输入法、字体、剪贴板、拖放。
在所有现代Linux发行版上,文件系统通常是用UTF-8编码的,应该不会造成问题。文件I/O默认使用UTF-8。
windows
Qt提供了完整的Unicode支持,包括输入法、字体、剪贴板、拖放和文件名。
文件I/O默认为Latin1,在QTextStream中使用Unicode选项。请注意,有些Windows程序不理解大端Unicode文本文件,即使在没有高级协议的情况下,Unicode标准规定了大端Unicode文本文件的顺序。
macOS
有关特定于macOS的翻译的详细信息,请参阅此处的Qt For macOS issues文档。
Internationalization with Qt | Qt 5.15