Qt 语言国际化 语言家相关

简述:Qt 提供了一种国际化方案,在程序使用过程中,不需要重启应用程序就可以实现语言的动态切换


1、实现语言国际化步骤 


要实现语言国际化,需要执行以下步骤:


A.  对用户可见的文本信息全部使用 tr()进行封装 

注意源码 utf-8 字符集;源码中需要翻译的字符串必须用英文,以防出现乱码


B.  创建语言文件 


打开 .pro文件,加入语言文件

TRANSLATIONS = $$PWD/i18n/Lidar_fr.ts \
        $$PWD/i18n/Lidar_en.ts \
        $$PWD/i18n/Lidar_ja.ts \
        $$PWD/i18n/Lidar_zh.ts


利用lupdate工具从源代码中扫描并提取需要翻译的字符串,生成 " .ts " 文件,即:

菜单栏 "工具"-> "外部-> "Qt语言家-> "更新翻译(lupdate)",将生成语言文件Lidar_fr.ts,Lidar_en.ts,Lidar_ja.ts,Lidar_zh.ts ;

或者,打开 Qt 5.7 for Desktop (MinGW 5.3.0 32bit) 命令行窗口,并进入 " .pro " 工程目录,执行命令:

lupdate  XXX.pro,便可生成 ".ts"翻译文件


C.编辑翻译语言文件 


利用 Linguist 工具 (Qt语言家) 来协助完成翻译工作。即启动Linguist 工具后,打开前面用 lupdate 生成的 " .ts "文件,对其中的字符串逐条进行翻译保存,主要是将源文对应的译文填写上。

另:由于 " .ts "文件用用了XML格式,所以也可以使用其他编辑器来打开 ".ts "文件并翻译


D.发布翻译文件


当翻译全部完成后,利用lrelease工具处理翻译好的 " .ts "文件,生成格式更为紧凑的 ".qm"文件,只有QTranslator能够正确识别它,即:

菜单栏 "工具"-> "外部" -> "Qt语言家" -> "发布翻译(lrelease)",便可生成对应的.qm "文件。


E.  加载翻译文件


[cpp]  view plain  copy
  1. QTranslator translator;  
  2. if (translator.load("Lidar_en.qm"":/translations")) { // 可以不带".qm"后缀名  
  3.     qApp->installTranslator(&translator);  
  4. }  

还可以使用别名

[cpp]  view plain  copy
  1. QTranslator translator;  
  2. if (translator.load("en"":/translations")) {   
  3.     qApp->installTranslator(&translator);  
  4. }  




F.  切换语言


method 1:

[cpp]  view plain  copy
  1. void MainWindow::Refresh()  
  2. {  
  3.     ui->listWidget->addItem(tr("item1"));  
  4.     ui->listWidget->addItem(tr("item2"));  
  5.     ui->listWidget->addItem(tr("item3"));  
  6. }  
  7.   
  8.   
  9. void MainWindow::actionEnglishToggled(bool state)  
  10. {  
  11.     if (state) {  
  12.         qApp->removeTranslator(&translator);  
  13.         if (translator.load("Lidar_en.qm"":/translations")) {  
  14.             qApp->installTranslator(&translator);  
  15.             this->Refresh();  
  16.         }  
  17.     }  
  18. }  
  19.   
  20. void MainWindow::actionFrancaisToggled(bool state)  
  21. {  
  22.     if (state) {  
  23.         qApp->removeTranslator(&translator);  
  24.         if (translator.load("Lidar_fr.qm"":/translations")) {  
  25.             qApp->installTranslator(&translator);  
  26.             this->Refresh();  
  27.         }  
  28.     }  
  29. }  
  30.   
  31. void MainWindow::actionJapaneseToggled(bool state)  
  32. {  
  33.     if (state) {  
  34.         qApp->removeTranslator(&translator);  
  35.         if (translator.load("Lidar_ja.qm"":/translations")) {  
  36.             qApp->installTranslator(&translator);  
  37.             this->Refresh();  
  38.         }  
  39.     }  
  40. }  
  41.   
  42.   
  43. void MainWindow::actionChineseToggled(bool state)  
  44. {  
  45.     if (state) {  
  46.         qApp->removeTranslator(&translator);  
  47.         if (translator.load("Lidar_zh.qm"":/translations")) {  
  48.             qApp->installTranslator(&translator);  
  49.             this->Refresh();  
  50.         }  
  51.     }  
  52. }  


method 2:

当语言进行切换时,需要调用 ui->retranslateUi(this); 更新主窗口。 如果非主窗口,则这个 installTranslator 函数会触发void changeEvent(QEvent *e) 事件。原因如下:

系统调用完 installTranslator 函数之后,系统会自动给程序中所有的 QWidget 以及其子类发送 QEvent::LanguageChange()信号,并告知changeEventevent产生。所以,在要切换语言的每个窗体中都要重写接受QEvent::LanguageChange()信号的changeEvent函数,从而实现了语言的动态切换。

注意加载主程序子插件程序翻译文件时的别名或者路径不要相同,否则子插件程序翻译有可能不生效。

[cpp]  view plain  copy
  1. /********************************************* 
  2.  * changeEvent一般是当前widget状态改变后触发的 
  3.  * 如字体改变、语言改变之类的。 
  4.  * 该方法主要捕获改变事件,当语言改变后,执行相关操作。 
  5. ********************************************/  
  6. void PlotViewerPlugin::changeEvent(QEvent* e) //重写的事件处理方法  
  7. {  
  8.     QWidget::changeEvent(e);   //让基类执行事件处理方法  
  9.     switch (e->type()) {  
  10.         case QEvent::LanguageChange:   //如果是语言改变事件  
  11.             if(ui) ui->retranslateUi(this); //更新UI的语言  
  12.             break;  
  13.         default:  
  14.             break;  
  15.     }  
  16. }  


注意:需要更新翻译,便重复" C " ~ " D " 步骤


2、样例



LangSwitch.pro

[cpp]  view plain  copy
  1. QT       += core gui  
  2.   
  3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets  
  4.   
  5. TARGET = LangSwitch  
  6. TEMPLATE = app  
  7.   
  8.   
  9. SOURCES += main.cpp\  
  10.         langswitch.cpp  
  11.   
  12. HEADERS  += langswitch.h  
  13. TRANSLATIONS = lang_en.ts \  
  14.                lang_zh.ts \  
  15.                lang_la.ts  


main.cpp

[cpp]  view plain  copy
  1. #include "langswitch.h"  
  2. #include <QApplication>  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     LangSwitch w;  
  8.     w.show();  
  9.       
  10.     return a.exec();  
  11. }  


langswitch.h

[cpp]  view plain  copy
  1. #ifndef LANGSWITCH_H  
  2. #define LANGSWITCH_H  
  3.   
  4. #include <QWidget>  
  5. #include <QComboBox>  
  6. #include <QLabel>  
  7.   
  8. class LangSwitch : public QWidget  
  9. {  
  10.     Q_OBJECT  
  11.       
  12. public:  
  13.     LangSwitch(QWidget *parent = 0);  
  14.     ~LangSwitch();  
  15. private slots:  
  16.     void changeLang(int index);  
  17.   
  18. private:  
  19.     void createScreen();  
  20.     void changeTr(const QString& langCode);  
  21.     void refreshLabel();  
  22.   
  23.     QComboBox* combo;  
  24.     QLabel* label;  
  25. };  
  26.   
  27. #endif // LANGSWITCH_H  


langswitch.cpp

[cpp]  view plain  copy
  1. #include "langswitch.h"  
  2. #include <QVBoxLayout>  
  3. #include <QTranslator>  
  4. #include <QApplication>  
  5. #include <QDebug>  
  6.   
  7. LangSwitch::LangSwitch(QWidget *parent)  
  8.     : QWidget(parent)  
  9. {  
  10.     createScreen();  
  11. }  
  12.   
  13. LangSwitch::~LangSwitch()  
  14. {  
  15.       
  16. }  
  17.   
  18. void LangSwitch::createScreen()  
  19. {  
  20.     combo = new QComboBox;  
  21.     combo->addItem("English""en");  
  22.     combo->addItem("Chinese""zh");  
  23.     combo->addItem("Latin""la");  
  24.   
  25.     label = new QLabel;  
  26.     refreshLabel();  
  27.   
  28.     QVBoxLayout* layout = new QVBoxLayout;  
  29.     layout->addWidget(combo, 1);  
  30.     layout->addWidget(label, 5);  
  31.   
  32.     setLayout(layout);  
  33.   
  34.     connect(combo, SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));  
  35.     changeLang(0);  
  36. }  
  37.   
  38. void LangSwitch::refreshLabel()  
  39. {  
  40.     label->setText(tr("TXT_HELLO_WORLD""Hello World"));  
  41. }  
  42.   
  43. void LangSwitch::changeLang(int index)  
  44. {  
  45.     QString langCode = combo->itemData(index).toString();  
  46.     changeTr(langCode);  
  47.     refreshLabel();  
  48. }  
  49.   
  50. void LangSwitch::changeTr(const QString& langCode)  
  51. {  
  52.     static QTranslator* translator;  
  53.   
  54.     if (translator != NULL)  
  55.     {  
  56.         qApp->removeTranslator(translator);  
  57.         delete translator;  
  58.         translator = NULL;  
  59.     }  
  60.     translator = new QTranslator;  
  61.     QString qmFilename = "lang_" + langCode;  
  62.     qDebug() << qmFilename;  
  63.     if (translator->load(QString("E:/.../LangSwitch/")+qmFilename))  
  64.     {  
  65.         qApp->installTranslator(translator);  
  66.     }  
  67. }  

转自:hebbely http://blog.csdn.net/hebbely/article/details/69388763   原创如有意见请回复,立即删除。

猜你喜欢

转载自blog.csdn.net/weixin_38293850/article/details/77679588