QT国际化


Qt的国际化和本地化

国际化是指在代码设计上加入能方便的移植到其他国家和地区的特性。而本地化是指将具有国际化支持的代码翻译成本国或地区的语言,是本地用户更容易使用。I18n是Internationalization的简写,l10n是Localization的简写。


在Qt中创建可以国际化的代码

最常见的是将要翻译的字符串加上tr语句,tr语句的标准语法是:

Context::tr(sourceText,comment), 比如 QString str2 = QTextEdit::'''tr'''(“Letter”,”paper size”);

Context(上下文)和comment(注释)是可以省略的,它们的意思分别是Context:用于指明该翻译文字所在的上下文,一般为类名。因为同样的一个字串在不同的环境中翻译出来是不一样的,比如都是死,皇帝是崩,普通老百姓就是死翘。comment: 用于指明要翻译文字的一个注释。因为作翻译的可能并不是写代码的人。比如spring既有弹簧的意思,又有春天的意思。designer里面选组建的时候,有一个blue spring(蓝色的弹簧)是用于addStretch()的,如果没加说明,有可能被翻译成蓝色的春天。

在写代码的时候,我们可能希望把所有的字符串都放在一个地方,而方便于我们自己集中作改动。真正用到的时候,用一个字符常量指针去访问。那么我们可能想到这样写代码

// Wrong,这种实现Qt不认识,无法作翻译

const char *appName=“OpenDrawer 2D”;
QString translated=tr(appName);

//ok, 需要使用QT_TR_NOOP字串来提醒Qt系统该翻译的字串

const char *appName=QT_TR_NOOP(“OpenDrawer 2D”);
QString translated=tr(appName);

QT_TR_NOOP的语法是QT_TR_NOOP(sourceText),它还有两个变体,语法如下

QT_TRANSLATE_NOOP ( context, sourceText )
QT_TRANSLATE_NOOP3 ( context, sourceText, comment )

对应介绍的context和comment,其意思应该不难理解

还有一种情况是在一个字串中有一部分来源于变量。那我们看看两种正误的写法


// wrong 这种写法无法被正确识别

statusBar()->showMessage('''tr'''(“Host ” + hostName+“ found”)//ok 利用了QString的arg()函数。在翻译时,需保留%1
 
statusBar()->showMessage('''tr'''(“Host %1 found”).arg(hostName)

在书写了含可翻译语句的程序后,我们来看看如何生成翻译文件


生成翻译文件

首先要修改.pro工程文件,比如在app.pro里加入

TRANSLATIONS+=app_en.ts app_zh_CN.ts app_zh_TW.ts #后面你可以加你想要翻译的各种版本
CONFIG += localize_deployment
 
SYMBIAN_SUPPORTED_LANGUAGES += zh_CN
SYMBIAN_LANG.zh_CN = 31

注:其中SYMBIAN_SUPPORTED_LANGUAGES ,SYMBIAN_LANG.zh_CN 两行是localize_deployment.prf 中缺少的两行,简体中文qs 文件只使用语言代号zh时 与系统解析的" 语言_区域"区域格式不符,请先这样设置。

然后在shell, 里执行如下语句( 在Qt SDK 中请打开Qt for Desktop的命令行,目前lupdate 命令没有为Qt for symbian生成的版本)

$ lupdate app.pro
$ linguist app_zh_CN.ts
$linguist app_zh_TW.ts 
$ lrelease *.ts

$ lupdate app.pro #会根据.pro里指示的内容,生成app_zh_CN.ts和app_zh_TW.ts$ linguist app_zh_CN.ts 翻译其中一个文件,linguist是一个图形化的工具,$linguist app_zh_TW.ts 翻译另一个,$ lrelease *.ts 将.ts文本文件转换成.qm二进制文件,会生成app_zh_CN.qm和app_zh_TW.qm,方便应用加载

.ts 是Text String的缩写;.qm是Qt Message的缩写所以翻译文件生成的流程就是.cpp —> .ts —>.qmlupdate是负责找出qt源代码中需要翻译的字符串的。会搜tr/QT_TR_NOOP/QT_TRANSLATE_NOOP /QT_TRANSLATE_NOOP3等语句linguist是手动翻译.ts文件的一个工具,真正加入本地语言是在这一步lrelease是将.ts转换成.qm的一个工具。需要提醒一下的,lupdate生成的.ts文件不会覆盖掉已经翻译过的.ts文件,只会更新其中的内容。所以其名字为languange update

有了翻译文件,我们看看系统是怎么加载翻译文件的。


加载翻译文件

一个例子,很简单的说明问题

QTranslator qt_translator;
QTranslator app_translator;
if( usersettings.language == SimpleChinese ) {
    // Qt’s own translations
    qt_translator.load("qt_zh");
    qApp->installTranslator( &qt_translator );
    // application translation
    app_translator.load("myprogram_zh");
    qApp->installTranslator( &app_translator );
}

这里,我们看到有两个翻译加载器,其中一个是加载应用程序的翻译文件,也就是我们在第二个步骤中生成的文件。另外一个是Qt系统的翻译文件,比如 Qt的版权信息,designer的一些菜单等,名字叫qt_后带一个语言版本。qt系统的翻译文件放在qt系统根目录下的translations目录中。生成执行程序后,需要把这两个 .qm 文件复制到执行程序目录下。这样程序才会找到翻译文件。或者在加载器中指定翻译文件的位置。例如:

QString locale = QLocale::system().name();
//本地化QT资源
QTranslator qtTranslator;
qtTranslator.load(QString("qt_") + locale + ".qm", a.applicationDirPath());
a.installTranslator(&qtTranslator);

有时候我们在系统启动的时候,就需要判断本地的语言,然后加载不同的翻译文件,那么代码就是如下结构

QString locale = QLocale::system().name();
QTranslator translator;
translator.load(QString("trollprint_") + locale);
app.installTranslator(&translator);

在pro文件中部署qm文件,使得在symbian系统下能方便的检索到qm文件,而不用再load方法中设置路径

symbian: {   
    addFiles.sources = helloworld_en.ts helloworld_zh_CN.qm helloworld_zh_TW.qm helloworld_zh_HK.qm
    addFiles.path = .
    DEPLOYMENT += addFiles
}

本地设置的语言,和我们的.qm前面部分并不完全一样,有一个.qm查询的过程,假如本地字语言名字是fr_CA.ISO8859-15,加载程序会按照 trollprint_fr_CA.ISO8859-15.qm,trollprint_fr_CA.qm,trollprint_fr.qm顺序来加载,如果以上都没有,将使用默认的语言


一个极其简单的例子

//main.cpp
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QTranslator translator;
    translator.load("hellotr_zh");
    app.installTranslator(&translator);
    QPushButton hello(QPushButton::tr("Hello world!"));
    hello.resize(100, 30);
    hello.show();
    return app.exec();
}



【原】Qt程序国际化

     Qt程序的国际化比较简单好用,现给出其主要步骤。
     1、对于中国的开发者而言,一般在界面和代码中都会直接使用中文。在ui界面中可以直接使用中文,但在代码中涉及到中文时,必须使用tr函数将中文字符串包含起来,这样Qt的翻译机制才能起作用。按照流程完成整个程序的开发,Qt的国际化可以在程序开发完成后再进行。
     2、如果要支持中文和英文两种语言,则需要在工程的.pro文件中添加配置:TRANSLATIONS = chinese.ts english.ts。
     3、在命令行中运行lupdate myapp.pro,或者通过Qt Creator的Tools菜单下的External—Qt语言家—Upate Translations来生成翻译文件chinese.ts和english.ts。ts文件是xml格式的,便于我们阅读和编辑。
     4、将翻译文件发送给专门的翻译人员进行翻译。当然,也可以使用Qt自带的Qt Linguist工具来协助我们进行翻译工作,但个人觉得直接编辑ts文件反而更加方便和快捷。
     5、翻译完成后,在命令行中运行lrelease myapp.pro,或者通过Qt Creator的Tools菜单下的External—Qt语言家—Release Translations来生成chinese.qm和english.qm。qm文件是二进制格式的,供Qt程序进行国际化。
     6、如果程序需要根据用户的本地设置来选择语言,则一般在main函数的开始处加载合适的qm文件,参考代码如下:

复制代码
1  int main( int argc,  char *argv[])
2 {
3     QApplication app(argc, argv);
4     QTranslator appTranslator;
5     appTranslator.load( " myapp_ " + QLocale::system().name(), qApp->applicationDirPath());
6     app.installTranslator(&appTranslator);
7     ...
8      return app.exec();
9 }
复制代码

     使用这种方式时,需要相应修改.pro文件中配置的ts文件的文件名。
     7、如果程序需要支持多语言的动态切换,则一般在主窗口中提供菜单或按钮供用户切换,参考代码如下:

复制代码
 1 MainWindow::MainWindow(QWidget *parent) :     
 2 QMainWindow(parent),     
 3 ui( new Ui::MainWindow),     
 4 m_bChinese( true
 5 {     
 6 ui->setupUi( this);     
 7 m_pTranslator =  new QTranslator( this);     
 8 connect(ui->pushButton,SIGNAL(clicked()), this,SLOT(changeLanguage()));     
 9 changeLanguage();
10 } 
11 
12 MainWindow::~MainWindow() 
13 {
14      delete ui; 
15 }
16  
17  void MainWindow::changeLanguage()
18 {      
19 QString qmName = m_bChinese ?  " chinese.qm " :  " english.qm ";
20 m_bChinese = !m_bChinese;
21  if (m_pTranslator->load(qmName, QApplication::applicationDirPath()))     
22 {         
23  qApp->installTranslator(m_pTranslator);         
24  ui->retranslateUi( this);
25 }
26 }
复制代码

8、如果在切换语言时,有其他非模态窗口存在,则只需要在该窗口类中重载changeEvent函数即可,参考代码如下:

复制代码
 1  void MyDlg::changeEvent(QEvent *e) 
 2 {     
 3 QDialog::changeEvent(e);     
 4  switch (e->type())     
 5 {     
 6  case QEvent::LanguageChange:         
 7 ui->retranslateUi( this);        
 8      break;     
 9  default:         
10  break;     
11 } 
12 }
复制代码

 

     另外,使用tr函数时,需要注意以下几点:
     1、tr函数中必须传入直接的字符串常量,而不能传入变量(除非使用QT_TR_NOOP等宏),比如像下面这样是无法进行多语言的翻译的。

1  const  char *pszText =  " hello world ";
2    setWindowTitle(tr(pszText));

     2、不能传入串联的字符串,比如:setWindowTitle(tr("hello " + text + " world")),Qt的翻译机制无法识别出这种情况(lupdate时将仅取"hello"字符串)。正确的做法如下:

1 setWindowTitle(tr( " hello %1 world ").arg(text));

     3、使用QT_TR_NOOP等宏,可以使tr函数中允许出现变量,比如:

1  const  char *pszText = QT_TR_NOOP( " hello world ");
2    setWindowTitle(tr(pszText));



Qt国际化——使用自带翻译包

复制代码
#ifndef QT_NO_TRANSLATION
    QString translatorFileName = QLatin1String("qt_");
    translatorFileName += QLocale::system().name();
    QTranslator *translator = new QTranslator(this);
    if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
        installTranslator(translator);
    else
        LOG_ERROR(QStringLiteral("加载中文失败"));

#endif
复制代码

    默认使用中文包:qt_Zh_CN.qm。

    开发环境会找到:C:\Qt\Qt5.0.2\5.0.2\msvc2010_opengl\translations类似目录。

 

    运行环境中,需要进行如下操作:

  1.  配置文件

      在应用程序目录增加qt.conf文件,内容如下:

[Paths]
Prefix = ./

     2. 复制文件

      将qt_Zh_CN.qm文件复制到应用程序的translations(自己创建)目录下。

 

     这样就会默认去查找./translations的翻译文件。

 

translatorFileName: 翻译文件的名字。
QLibraryInfo::location(QLibraryInfo::TranslationsPath):文件位置

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值