Live & Learn
分类: 嵌入式
2010-08-30 16:45:57
作者:孙晓明,讲师。
Qt中的国际化方法与GNU gettext类似,它提供了tr()函数与gettext()函数对应,而翻译后的资源文件则以.qm来命名,且其国际化的机制与它的元对象系统密切相关。
在支持国际化的过程中,程序员的工作一般是在所编写的代码中加入国际化的支持,这在Qt中利用QString、QTranslator等类和tr()函数能够很方便的完成。程序员所需要做的工作有如下一些:
1.使用QString对象来表示所有用户可见的文本。由于QString内部使用Unicode编码来实现,它可以用来表示所有需要向用户呈现的文本。当然对于仅仅程序员可见的文本并不需要都变成QString对象,可利用Qt提供的QCString或者原始的char *。
2.使用tr()函数来取得所有需要翻译的文本。在Qt的翻译机制下,QObject::tr()函数可以帮我们取得翻译之后的文本。对于从QObject继承而来的类,QObject::tr()函数最终由QMetaObject::tr()来实现,Q_OBJECT宏的定义以及在qmetaobject.cpp中QMetaObject::tr()的实现。在某些时候如果无法使用QObject::tr()函数,我们还可以直接调用QCoreApplication::translate()来取得翻译之后的字符串。
3.使用QString::arg()来组织动态文本。有些时候一段文本需要由一些静态文本和动态变量组合起来,比如常见的情况:printf(“The value of i is: %d”, i)。对于这种动态文本的翻译,由于语言习惯的问题,如果简单的采用这种连接字符串的方法,可能会带来一些问题。比如下面的字符串用来表示任务的完成情况:
QString m = tr(“Mission status: “ )+ x + tr(“of “) + y +tr(”are completed”);
其中x和y是动态的变量,三个字符串被x和y分隔开,它们无法被很好的翻译——”x of y”是英语中分数的表示方法,比如4 of 5是分数4/5,在不同的语言中分子和分母的位置可能是颠倒的,这种情况下数字4和5的位置在翻译的时候无法被正确的放置,可见孤立地翻译被分隔开的字符串是不行的,改进的办法是使用
QString::arg()方法:
QString m = tr(“Mission status: %1 of %2 are completed”).arg(x).arg(y);
这样翻译工作者可以将整个字符串进行翻译,并将参数%1和%2放到正确的位置。
4.利用QTranslator::load()和QCoreApplication::installTranslator()来读取对应的翻译之后的资源文件。翻译工作者将提供包含有翻译之后的字符串的资源文件*.qm,程序员还需要做的是定义QTranslator对象,并用load()函数读取相应的.qm文件,然后利用QCoreApplication::installTranslator()函数来安装QTranslator对象。
对于翻译工作者,主要是利用Qt提供的工具lupdate、linguist和lrelease(它们都可以在Qt安装目录的bin文件夹下找到)来协助翻译工作并生成最后需要的.qm文件,包括以下内容:
1.利用lupdate工具从源代码中扫描并提取需要翻译的字符串,生成.ts文件。类似编译时用到的qmake,运行lupdate时我们也需要指定一个.pro的文件,这个.pro文件可以单独创建,也可以利用编译时用到的.pro文件,只需要定义好变量TRANSLATIONS就可以了,具体用法可以参见后面的小例子。
2.利用linguist工具来协助完成翻译工作,即打开前面用lupdate生成的.ts文件,对其中的字符串逐条进行翻译并保存。由于.ts文件采用了xml格式,我们也可以用其它编辑器来打开.ts文件并翻译。
3.利用lrelease工具处理翻译好的.ts文件,生成格式更为紧凑的.qm文件。这便是翻译工作者最终需要提供给程序员的资源文件,它所占的空间比.ts文件小,但基本不具有可读性,只有QTranslator能正确的识别它。