Qt动态多语言的实现

Qt对于多语言提供了QTranslator的接口,只要在程序启动时进行安装,然后动态改变QTranslator的加载即可。下面是效果图(英文/简体/繁体)。

Qt动态多语言的实现

选择不同的语言,界面会随着切换。这要如何实现呢?QTranslator会加载*.qm的语言档,而该文件是从*.ts转换而来的。所以我们首先要做的是制作*.ts档。步骤如下

1.在项目的Resource Files的位置右击,添加新建项,选择.cpp类型的文件,然后将名字命名为ts的后缀,比如simplify.ts。

2.双击simplify.ts,在里面添加ts必要的内容。

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE TS>  
  3. <TS version="2.0">  
  4.       
  5. </TS>  
3.右击ts档,选择lupdate,更新ts档。如下图。
Qt动态多语言的实现


4.查看ts档。右击ts档->打开方式->XML(文本)编译器->双击或确定。(ts档是xml格式,选用xml编译器,便于编辑)。内容如下

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE TS>  
  3. <TS version="2.0">  
  4. <context>  
  5.     <name>LanguagesDialog</name>  
  6.     <message>  
  7.         <source>Languages</source>  
  8.         <translation type="unfinished"></translation>  
  9.     </message>  
  10.     <message>  
  11.         <source>English</source>  
  12.         <translation type="unfinished"></translation>  
  13.     </message>  
  14.     <message>  
  15.         <source>Simplify</source>  
  16.         <translation type="unfinished"></translation>  
  17.     </message>  
  18.     <message>  
  19.         <source>Traditional</source>  
  20.         <translation type="unfinished"></translation>  
  21.     </message>  
  22. </context>  
  23. </TS>  
5.编译ts档。代码中使用tr转换的字段都被提取了出来,并且存在了message字段下。message字段下的source是代码中的源字段,translation就是转换的内容。我们将type="unfinished"删除,然后添加内容。编译后的内容如下。

[html] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE TS>  
  3. <TS version="2.0">  
  4.     <context>  
  5.         <name>LanguagesDialog</name>  
  6.         <message>  
  7.             <source>Languages</source>  
  8.             <translation >多语言</translation>  
  9.         </message>  
  10.         <message>  
  11.             <source>English</source>  
  12.             <translation >英文</translation>  
  13.         </message>  
  14.         <message>  
  15.             <source>Simplify</source>  
  16.             <translation >简体</translation>  
  17.         </message>  
  18.         <message>  
  19.             <source>Traditional</source>  
  20.             <translation >繁体</translation>  
  21.         </message>  
  22.     </context>  
  23. </TS>  

6.繁体档(traditional.ts)和英文档(english.ts)按同样的方法制作。也可直接将simpify.ts复制,然后改名。

7.生成qm档。选中ts->右击->lrelease.如下图

Qt动态多语言的实现
8.查看qm档是否生成成功。也就是说,生成了对应的english.qm、simplify.qm、traditional.qm。如下图

Qt动态多语言的实现

注:对于ts和qm档的制作也可以直接使用qt的Qt Linguist工具来制作。

qm制作完成后,在代码中要实现相应的切换和调用。下面是实现代码。

main.cpp

[cpp] view plain copy
  1. #include <QtWidgets/QApplication>  
  2. #include "LanguagesDialog.h"  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     LanguagesDialog languagesDialog;  
  8.     a.installTranslator(languagesDialog.qTranslator);//注意:一定要加上这一句,才能将转换器安装到程序中,否则语言切换会失败。  
  9.     languagesDialog.show();  
  10.     return a.exec();  
  11. }  

LanguagesDialog.h

[cpp] view plain copy
  1. #include <QtWidgets>  
  2.   
  3. class LanguagesDialog:public QDialog  
  4. {  
  5.     Q_OBJECT  
  6. public:  
  7.     LanguagesDialog();  
  8.     QTranslator *qTranslator;  
  9. protected:  
  10.     void changeEvent(QEvent *);  
  11.   
  12.     private slots:  
  13.         void languageChanged();  
  14.   
  15. private:  
  16.     void translateUi();  
  17.     QGroupBox *languages;  
  18.   
  19.     QRadioButton *english;  
  20.     QRadioButton *simplify;  
  21.     QRadioButton *traditional;  
  22.   
  23. };  


LanguagesDialog.cpp

[cpp] view plain copy
  1. #include "LanguagesDialog.h"  
  2.   
  3. LanguagesDialog::LanguagesDialog():QDialog()  
  4. {  
  5.     languages=new QGroupBox(this);  
  6.     english=new QRadioButton(this);  
  7.     simplify=new QRadioButton(this);  
  8.     traditional=new QRadioButton(this);  
  9.     qTranslator=new QTranslator();  
  10.   
  11.     english->setChecked(true);  
  12.     qTranslator->load("english");  
  13.   
  14.     QVBoxLayout *baselayout=new QVBoxLayout(this);  
  15.     baselayout->addWidget(languages);  
  16.   
  17.     QVBoxLayout *radioLayout=new QVBoxLayout(languages);  
  18.     radioLayout->addWidget(english);  
  19.     radioLayout->addWidget(simplify);  
  20.     radioLayout->addWidget(traditional);  
  21.   
  22.     connect(english,SIGNAL(toggled(bool)),this,SLOT(languageChanged()));  
  23.     connect(simplify,SIGNAL(toggled(bool)),this,SLOT(languageChanged()));  
  24.     connect(traditional,SIGNAL(toggled(bool)),this,SLOT(languageChanged()));  
  25.   
  26.     translateUi();  
  27. }  
  28.   
  29. void LanguagesDialog::translateUi()  
  30. {  
  31.     languages->setTitle(tr("Languages"));//用tr转换的字段,会被自动抽取出来,将利用QTranslator来转换。  
  32.   
  33.     english->setText(tr("English"));  
  34.     simplify->setText(tr("Simplify"));  
  35.     traditional->setText(tr("Traditional"));  
  36. }  
  37.   
  38. void LanguagesDialog::changeEvent(QEvent *event)  
  39. {      
  40.     if (event->type()==QEvent::LanguageChange)  
  41.     {  
  42.         translateUi();//更新界面  
  43.     }  
  44.     else  
  45.     {  
  46.         QDialog::changeEvent(event);  
  47.     }  
  48. }  
  49.   
  50. ////////////////////////////////////////////////////////////  
  51. ///slots  
  52. void LanguagesDialog::languageChanged()  
  53. {  
  54.     if (english->isChecked())  
  55.     {  
  56.         qTranslator->load("english");//加载英文  
  57.     }  
  58.     else if(simplify->isChecked())  
  59.     {  
  60.         qTranslator->load("simplify");//加载简体  
  61.     }    
  62.     else if(traditional->isChecked())  
  63.     {  
  64.         qTranslator->load("traditional");//加载繁体  
  65.     }    
  66. }  

如果需要与操作系统的语言相匹配,那么可以利用QLocale::system().name()获取系统的语言信息,然后载入对应的语言档。简易代码如下

[cpp] view plain copy
  1. int main(int argc, char *argv[])  
  2. {  
  3.     QApplication a(argc, argv);    
  4.     QTranslator translator;  
  5.     translator.load(QLocale::system().name());  
  6.     a.installTranslator(&translator);  
  7.     //other thing.  
  8.     return a.exec();  
  9. }  

注意:QLocale::system().name()获取的语言信息是依据ISO_639-1和ISO_3166-1生成的,一般是语言_区域的形式,比如中文代号是zh,中国的代号是CN,所以组合出来的结果就是zh_CN。所以这就要求我们在制作i18n(国际化)和l10n(本地化)的文言档时,最好是依照这种规范生成相应的ts和qm档。比如刚刚可以是zh_CN.ts和zh_CN.qm。当然可以适当的加入前缀,以便于区分不同的程序(LanguageDialog_zh_ch)。前缀可以用translator.load(QString("LanguageDialog_")+QLocale::system().name())组合而成。


原文链接:http://blog.csdn.net/xxdddail/article/details/17551263