Qt
Qt
目录
国际化
参考:
- 《Qt5开发及实例(第四版)》
- 【W3Cschool】Qt 国际化
- 【gitbooks】国际化
基本概念
简概
编码
- Qt使用Unicode作为内部编码,可以同时支持多种编码
- 为Qt添加一种编码的支持也比较方便,只要添加该编码和Unicode的转换编码即可
Qt自己定义的Locale机制
- 在编码支持和信息文件(Message File)的翻译上弥补了目前UNIX上所普遍采用的Local和gettext的不足之处
- 可以使Qt的同一组件上同时显示不同编码的文本
国际化方案
- 不是采用INI配置文件的方式,而措施GNU gettext类似
- 提供了
tr()
与gettext()
函数对应,而翻译后的资源文件则以.qm
命名
国际化支持的实现
使用
QString对象
表示所有用户可见的文本- 原因:QString内部使用Unicdoe编码
- 对于仅程序员可见的文本也可以使用QCString或原始的char *
使用
tr()
函数获取所有需要翻译的文本- 在某些时候,如果无法使用
QObject::tr()
函数,则可以直接调用QCoreApplication::translate()
取得翻译后的字符串
- 在某些时候,如果无法使用
使用
QString::arg()
方法组织动态文本- 如
QString m = tr("Mission status: %1 of %2 are completed").arg(x).arg(y);
而不要使用字符串连接的方法 - 这样,翻译者可以将整个字符串进行翻译,并将参数%1和%2放到正确的位置
- 如
使用
QTranslator::load()
和QCoreApplication::installTranslator()
函数读取翻译后的.qm资源文件- 程序猿需要定义
QTranslator
对象并使用load()
函数读取响应的.qm
文件 - 利用
QCoreApplication::installTranslator()
函数安装QTranslator对象
- 程序猿需要定义
翻译工作:.qm
文件的生成
对于翻译工作者,主要利用Qt提供的lupdate、linguist和lrelease协助翻译并生成最后需要的.qm文件
lupdate 工具
- 从源代码中扫描并提取需要翻译的字符串,生成
.ts
文件 - 需要在
.pro
文件中定义好变量TRANSLATIONS
- 从源代码中扫描并提取需要翻译的字符串,生成
linguist 工具
- 打开
.ts
文件,对其中字符串逐条进行翻译并保存 .ts
文件采用XML格式,所以也可以使用其他编辑器来打开.ts文件翻译
- 打开
lrelease 工具
- 处理翻译好的
.ts
文件,生成格式更紧凑的.qm
文件 - 它所占空间比.ts文件小,但基本不具有可读性(二进制),只有
QTranslator
能正确识别它
- 处理翻译好的
使用
基本流程
修改.pro文件
编译。若不先编译就进行下面步骤则生成,则生成的.ts文件只是一个仅有标题栏的框架(如下)
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> <TS version="2.1" language="TextEditor_zh_CN"></TS>
编译完成后打开Qt命令行窗口,进入工程目录,执行
lupdate TestHello.pro
,生成.ts文件(lupdate –verbose yourproject.pro) 如果没有编译则提示 ” Found 1 source text “ 若已完成编译则提示 “ Found $n source text(s) ”运行Linguist并打开,ts文件,选择源语言和目标语言。选择要翻译的字符串并翻译后,保存退出
发布,或者在Qt命令行输入
lrelease TestHello.pro
生成.qm文件修改源代码,使用
#include <QTranslator>
来翻译,注释部分为需要添加的代码#include <QTranslator> // 头文件 int main(int argc, char *argv[]) { QApplication a(argc, argv); QTranslator *translator = new QTranslaotr; // 实例化QTranslator类 translaotr->load("D:/.../TestHello.qm"); // 加载.qm翻译文件【注意为绝对路径】 a.installTranslator(translator); // 翻译 MainWindow w; w.show(); return a.exec(); }
选择语言
其他
tr()
函数
参考:https://blog.csdn.net/mfc11/article/details/6591134
在论坛中漂,经常遇到有人遇到tr相关的问题。用tr的有两类人:
- 因为发现中文老出问题,然后搜索,发现很多人用tr,于是他也开始用tr
- 另一类人,确实是出于国际化的需要,将需要在界面上显示的文件都用tr包起来,这又分两种:
- 用tr包住英文(最最推荐的用法,源码英文,然后提供英文到其他语言的翻译包)
- 用tr包住中文(源码用中文,然后提供中文到其他语言的翻译包)
注意哦,如果你正在用tr包裹中文字符,却不属于(2b),那么,这是个信号:
- 你在误用tr
- 你需要的是QString,而不是tr
tr()的三个参数
static QString tr(const char *sourceText, const char *comment = 0, int n = -1);
虽然我们只传了一个参数,但是实际上 tr()函数是接受3个参数的。第一个参数是我们需要翻译的文字,如果使用 qm 文件有对应的字符串,则使用对应的字符串进行替换,否则将显示 sourceText 参数指定的字符串。第二个参数是一个注释,用于解释前面的 sourceText 的含义,比如 table 一词既可以当做桌子翻译,又可以当成表格翻译,这时你就需要提供这个注释。或许你会问,使用翻译工具的时候不是有源代码吗?问题是,有可能人家不使用这个翻译工具,而使用别的工具,这样就不能保证会有这个源代码的预览;并且,你的程序不一定必须要发布源代码的;翻译人员往往只得到我们导出的 ts 文件,如果你加上注释,就可以方便翻译人员进行翻译。最后一个参数 n 用于指定字符串是否为复数。我们知道,很多语言,比如英语,很多名词的单复数形式是不相同的,为了解决这个问题,Qt 在 tr()函数中提供了一个参数 n。请看如下代码:
翻译人员往往只得到我们导出的 ts 文件
int n = messages.count();
showMessage(tr("%n message(s) saved", "", n));
对于 n 的值的不同,Qt 会翻译成不同的文字,例如:
n | 翻译结果 |
---|---|
0 | 0 message saved |
1 | 1 message saved |
2 | 2 messages saved |
5 | 5 messages saved |