跳至主要內容

Qt

LincZero大约 5 分钟

Qt

目录

国际化

参考:

基本概念

简概

  • 编码

    • Qt使用Unicode作为内部编码,可以同时支持多种编码
    • 为Qt添加一种编码的支持也比较方便,只要添加该编码和Unicode的转换编码即可
  • Qt自己定义的Locale机制

    • 在编码支持和信息文件(Message File)的翻译上弥补了目前UNIX上所普遍采用的Local和gettext的不足之处
    • 可以使Qt的同一组件上同时显示不同编码的文本
  • 国际化方案

    • 不是采用INI配置文件的方式,而措施GNU gettext类似
    • 提供了tr()gettext()函数对应,而翻译后的资源文件则以.qm命名

国际化支持的实现

翻译工作:.qm文件的生成

对于翻译工作者,主要利用Qt提供的lupdate、linguist和lrelease协助翻译并生成最后需要的.qm文件

  • lupdate 工具

    • 从源代码中扫描并提取需要翻译的字符串,生成.ts文件
    • 需要在.pro文件中定义好变量TRANSLATIONS
  • linguist 工具

    • 打开.ts文件,对其中字符串逐条进行翻译并保存
    • .ts文件采用XML格式,所以也可以使用其他编辑器来打开.ts文件翻译
  • lrelease 工具

    • 处理翻译好的.ts文件,生成格式更紧凑的.qm文件
    • 它所占空间比.ts文件小,但基本不具有可读性(二进制),只有QTranslator能正确识别它

使用

基本流程

  1. 修改.pro文件

  2. 编译。若不先编译就进行下面步骤则生成,则生成的.ts文件只是一个仅有标题栏的框架(如下)

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE TS>
    <TS version="2.1" language="TextEditor_zh_CN"></TS>
    
  3. 编译完成后打开Qt命令行窗口,进入工程目录,执行lupdate TestHello.pro,生成.ts文件(lupdate –verbose yourproject.pro) 如果没有编译则提示 ” Found 1 source text “ 若已完成编译则提示 “ Found $n source text(s) ”

  4. 运行Linguist并打开,ts文件,选择源语言和目标语言。选择要翻译的字符串并翻译后,保存退出

  5. 发布,或者在Qt命令行输入lrelease TestHello.pro生成.qm文件

  6. 修改源代码,使用#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翻译结果
00 message saved
11 message saved
22 messages saved
55 messages saved