Qt多语言实现和动态切换(国际化)


Qt 界面实现多国语言切换实例是本文要介绍的内容,一直认为Qt界面相对于还是很好实现的一种开发。多国语界面的实现,在MFC中是很别扭的。以前在作MFC时,实现多国语言界面,只有把资源文件做成各个语言的资源DLL,在程序启动时,根据选择判断选择载入哪个DLL来获取资源。MFC的资源也是分语言的,在创建资源的时候要选择,但是这样的实现还有有弊端。最根本的原因是MFC的资源文件不是Unicode编码的,而是不同语言的本地码,至少VC6是这样的。这样在中文系统中载入日文的资源,界面出现的是乱码。

Qt内部采用的全Unicode编码,这从根本上保证了多国语界面实现的正确性和便捷性。Qt本身提供的linguist工具,就是来实现这个翻译过程的。实现多国语的步骤大体上说来有这么几步:

1、在需要被翻译的字符串前面标识tr,如QString str=tr(“hello,world!”); ,这很重要,因为翻译工具会把源码中tr标识的字符串提取出来,翻译成其他语言,如果没有用tr标识的,不会被工具提取。在界面中输入的文字,默认已经是加上tr的了,所以在翻译时也能看见。

点击(此处)折叠或打开

  1. ui->pushButton_CN->setText(tr("Chinese"));
  2.     ui->pushButton_DE->setText(tr("Germen"));
  3.     ui->pushButton_EN->setText(tr("English"));
  4.     ui->pushButton->setText(tr("Switch"));
  5.     ui->radioButton_CN->setText(tr("Chinese"));
  6.     ui->radioButton_DE->setText(tr("Germen"));
  7.     ui->radioButton_EN->setText(tr("English"));
  8.     setWindowTitle(tr("MainWindow"));
建议:在程序中的字符串使用英文,汉语等通过多国语翻译来实现,而不要采取把汉字写在代码中。


2、在工程文件***.pro中,添加一项 TRANSLATIONS +=    ***.ts  ****.ts 扩展名为.ts是翻译的源文件,表示生成这几个文件。一般我们会在命名中把区域加进去,更好的注释这些文件是用于什么语言的,比如中文大多会这样命名 myapp_zh_CN.ts, zh_CN表示的就是中国。

点击(此处)折叠或打开

  1. TRANSLATIONS+=cn.ts \
  2.               de.ts \
  3.               en.ts


3、使用lupdate工具提取翻译源文件, 命令是这样的  #lupdate ***.pro ,或者通过Qt Creator的图形界面来生成***.ts文件。lupdate会解析***.pro即工程文件,生成TRANSLATIONS中的 ***.ts 几个文件,这些文件可以被linguist工具打开,按照提示一个一个的翻译成需要的文件,然后保存就OK,

linguist的使用很简单,一看界面基本就会了。上面提到的这些工具都是Qt自带的。

4、使用lrelease工具发布翻译文件的二进制文件,这样在程序运行时载入会大大的加快速度。使用方式是#lrelease ***.pro,或者通过Qt Creator的图形界面来生成***.qm文件。这个工具会提示你多少语句被翻译,多少被忽略了等。生成的文件是 ***.qm,于同名的 ***.ts只是换了一个扩展名。而这才是我们程序需要使用到的文件。

5、使用***.qm文件。关于这个,我想还是摘抄书上的原文来说明一下:

切换语言分为两种情况:
   方法1:手动导入XXX.qm文件,在更新tr("XXX")的文件。如果有子窗口的话,子窗口通过模式对话框显示,子窗口翻译可以更新;如果用非模式对话框,子窗口翻译无法更新

1. 程序载入的时候,根据当前的区域设置,自动选择语言包(.qm),即可;

2. 要求在程序运行过程中动态切换语言,需要

点击(此处)折叠或打开

  1. void MainWindow::loadLanguage()
  2. {
  3.     QTranslator translator;
  4.     bool b = false;
  5.     b = translator.load(":/Lan/cn");
  6.     qApp->installTranslator(&translator);
  7.     ui->radioButton_CN->setChecked(true);
  8.     RefreshUI();
  9. }

  10. void MainWindow::RefreshUI()
  11. {
  12.     ui->pushButton_CN->setText(tr("Chinese"));
  13.     ui->pushButton_DE->setText(tr("Germen"));
  14.     ui->pushButton_EN->setText(tr("English"));
  15.     ui->pushButton->setText(tr("Switch"));
  16.     ui->radioButton_CN->setText(tr("Chinese"));
  17.     ui->radioButton_DE->setText(tr("Germen"));
  18.     ui->radioButton_EN->setText(tr("English"));
  19.     setWindowTitle(tr("MainWindow"));
  20. }

点击(此处)折叠或打开

  1. void MainWindow::loadLanguage()
  2. {
  3.     QTranslator translator;
  4.     bool b = false;
  5.     b = translator.load(":/Lan/cn");
  6.     qApp->installTranslator(&translator);
  7.     ui->radioButton_CN->setChecked(true);
  8.     RefreshUI();
  9. }

  10. void MainWindow::RefreshUI()
  11. {
  12.     ui->pushButton_CN->setText(tr("Chinese"));
  13.     ui->pushButton_DE->setText(tr("Germen"));
  14.     ui->pushButton_EN->setText(tr("English"));
  15.     ui->pushButton->setText(tr("Switch"));
  16.     ui->radioButton_CN->setText(tr("Chinese"));
  17.     ui->radioButton_DE->setText(tr("Germen"));
  18.     ui->radioButton_EN->setText(tr("English"));
  19.     setWindowTitle(tr("MainWindow"));
  20. }
方法2:手动导入XXX.qm文件,通过ui文件,当调用qApp->installTranslator(&translator);时就会给ui文件发送 QEvent :: LanguageChange 事件,通过调用ui->ui->retranslateUi()来更新tr("XXX")字段
需要说明的时, 一般我们使用设计器来设计 界面 UI,也就是程序源码中我们看到的 ***.ui文件,在载入翻译器后,我们应该调用 ui->retranslateUi() ,这个函数实际上就是把 界面 控件的text重新载入一遍,可以在 ui_***.cpp中看到该函数的实现。

点击(此处)折叠或打开

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"


  3. MainWindow::MainWindow(QWidget *parent) :
  4.     QMainWindow(parent),
  5.     ui(new Ui::MainWindow)
  6. {
  7.     ui->setupUi(this);
  8.   // Refresh();
  9.     initial();
  10. }

  11. MainWindow::~MainWindow()
  12. {
  13.     delete ui;
  14.     lan.close();
  15. }
  16. void MainWindow::initial()
  17. {
  18.     m_lan_flag = LAN_EN;
  19.     m_translator.load(":/Lan/en");
  20.     ui->radioButton_EN->setChecked(true);
  21.     qApp->installTranslator(&m_translator);
  22.     RefreshUI();
  23. }

  24. void MainWindow::RefreshUI()
  25. {
  26.     ui->pushButton_CN->setText(tr("Chinese"));
  27.     ui->pushButton_DE->setText(tr("Germen"));
  28.     ui->pushButton_EN->setText(tr("English"));
  29.     ui->pushButton->setText(tr("Switch"));
  30.     ui->radioButton_CN->setText(tr("Chinese"));
  31.     ui->radioButton_DE->setText(tr("Germen"));
  32.     ui->radioButton_EN->setText(tr("English"));
  33.     setWindowTitle(tr("MainWindow"));
  34. }

  35. void MainWindow::on_pushButton_EN_clicked()
  36. {
  37.     m_lan_flag = LAN_EN;
  38.     autoLoadLanguage();
  39. }

  40. void MainWindow::on_pushButton_CN_clicked()
  41. {
  42.     m_lan_flag = LAN_CN;
  43.    // ui->radioButton_CN->setChecked(true);
  44.     autoLoadLanguage();
  45. }

  46. void MainWindow::on_pushButton_DE_clicked()
  47. {
  48.     m_lan_flag = LAN_DE;
  49.     autoLoadLanguage();
  50. }

  51. void MainWindow::on_pushButton_clicked()
  52. {
  53.     // Method 1: Load language direct
  54.     loadLanguage();

  55.     // Method 2: Auto load language by QEvent::LanguageChange
  56.    // autoLoadLanguage();


  57. }

  58. void MainWindow::on_radioButton_CN_clicked()
  59. {
  60.     m_lan_flag = LAN_CN;
  61.     ui->radioButton_CN->setChecked(true);
  62.     autoLoadLanguage();
  63. }
  64. void MainWindow::on_radioButton_EN_clicked()
  65. {
  66.     m_lan_flag = LAN_EN;
  67.     ui->radioButton_EN->setChecked(true);
  68.     autoLoadLanguage();
  69. }
  70. void MainWindow::on_radioButton_DE_clicked()
  71. {
  72.     m_lan_flag = LAN_DE;
  73.     ui->radioButton_DE->setChecked(true);
  74.     autoLoadLanguage();
  75. }
  76. void MainWindow::loadLanguage()
  77. {
  78.     QTranslator translator;
  79.     bool b = false;
  80.     b = translator.load(":/Lan/cn");
  81.     qApp->installTranslator(&translator);
  82.     ui->radioButton_CN->setChecked(true);

  83.     // Method A: model dialog, translate is success in sub dialog
  84.     //lan.exec();
  85.     
  86.     // Method B: model dialog, translate is success in sub dialog
  87.     lan.show();
  88.     lan.raise();
  89.     lan.activateWindow();

  90. }
  91. void MainWindow::autoLoadLanguage()
  92. {
  93.     switch(m_lan_flag)
  94.     {
  95.     case LAN_CN:
  96.        //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
  97.          m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
  98.         break;
  99.     case LAN_EN:
  100.         m_translator.load(QString(":/Lan/en"));
  101.         break;
  102.     case LAN_DE:
  103.         m_translator.load(QString(":/Lan/de"));
  104.         break;
  105.     }
  106.     qApp->installTranslator(&m_translator);

  107. }
  108. // Method 2: Use ChangeEvent to retranslateUi
  109. void MainWindow::changeEvent(QEvent *event)
  110. {
  111.     if(event->type() == QEvent::LanguageChange)
  112.         ui->retranslateUi(this);
  113.     else
  114.         QWidget::changeEvent(event);
  115. }

    6,导入XXX.qm文件,
1) 可以通过XXX.qrc文件导入,但是通过XXX.qrc文件导入的话,每次qm文件有修改或更新,需要从新导入


2) 也可以通过相对或绝对路径指定。



点击(此处)折叠或打开

  1. case LAN_CN:
  2.        //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address

7、在帮助文档中,关于 QTranslator::load有这样一句话。

The data is not copied. The caller must be able to guarantee that data will not be deleted or modifiled.

这段话明确的说明了,QTranslator在load以后,并没有把qm文件中的数据拷贝一份,而是在需要的时候去查询字符串。如果qm在这期间被删除或修改,对程序都是有影响的。扩展开来,QTranslator必须保证要一直有效,如果在函数中定义的局部变量,函数结束后就自动释放掉了,那么翻译工作就不能正常进行。所以建议在private中定义个成员变量 QTranslator* app_translator;来确保整个翻译工作的正确性。

程序主要代码和运行效果

XXX.pro 文件

点击(此处)折叠或打开

  1. QT += core gui

  2. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

  3. TARGET = LanguageChange
  4. TEMPLATE = app


  5. SOURCES += main.cpp\
  6.         mainwindow.cpp \
  7.     languagewidget.cpp

  8. HEADERS += mainwindow.\
  9.     languagewidget.h

  10. FORMS += mainwindow.ui \
  11.     languagewidget.ui
  12. RESOURCES += lan.qrc


  13. TRANSLATIONS+=cn.ts \
  14.               de.ts \
  15.               en.ts

主窗口代码

点击(此处)折叠或打开

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"


  3. MainWindow::MainWindow(QWidget *parent) :
  4.     QMainWindow(parent),
  5.     ui(new Ui::MainWindow)
  6. {
  7.     ui->setupUi(this);
  8.   // Refresh();
  9.     initial();
  10. }

  11. MainWindow::~MainWindow()
  12. {
  13.     delete ui;
  14.     lan.close();
  15. }
  16. void MainWindow::initial()
  17. {
  18.     m_lan_flag = LAN_EN;
  19.     m_translator.load(":/Lan/en");
  20.     ui->radioButton_EN->setChecked(true);
  21.     qApp->installTranslator(&m_translator);
  22.     RefreshUI();
  23. }

  24. void MainWindow::RefreshUI()
  25. {
  26.     ui->pushButton_CN->setText(tr("Chinese"));
  27.     ui->pushButton_DE->setText(tr("Germen"));
  28.     ui->pushButton_EN->setText(tr("English"));
  29.     ui->pushButton->setText(tr("Switch"));
  30.     ui->radioButton_CN->setText(tr("Chinese"));
  31.     ui->radioButton_DE->setText(tr("Germen"));
  32.     ui->radioButton_EN->setText(tr("English"));
  33.     setWindowTitle(tr("MainWindow"));
  34. }

  35. void MainWindow::on_pushButton_EN_clicked()
  36. {
  37.     m_lan_flag = LAN_EN;
  38.     ui->radioButton_EN->setChecked(true);
  39.     autoLoadLanguage();
  40. }

  41. void MainWindow::on_pushButton_CN_clicked()
  42. {
  43.     m_lan_flag = LAN_CN;
  44.     ui->radioButton_CN->setChecked(true);
  45.     autoLoadLanguage();
  46. }

  47. void MainWindow::on_pushButton_DE_clicked()
  48. {
  49.     m_lan_flag = LAN_DE;
  50.     ui->radioButton_DE->setChecked(true);
  51.     autoLoadLanguage();
  52. }

  53. void MainWindow::on_pushButton_clicked()
  54. {
  55.     // Method 1: Load language direct
  56.     //loadLanguage();

  57.     // Method 2: Auto load language by QEvent::LanguageChange
  58.     autoLoadLanguage();


  59. }

  60. void MainWindow::on_radioButton_CN_clicked()
  61. {
  62.     m_lan_flag = LAN_CN;
  63.     ui->radioButton_CN->setChecked(true);
  64.     autoLoadLanguage();
  65. }
  66. void MainWindow::on_radioButton_EN_clicked()
  67. {
  68.     m_lan_flag = LAN_EN;
  69.     ui->radioButton_EN->setChecked(true);
  70.     autoLoadLanguage();
  71. }
  72. void MainWindow::on_radioButton_DE_clicked()
  73. {
  74.     m_lan_flag = LAN_DE;
  75.     ui->radioButton_DE->setChecked(true);
  76.     autoLoadLanguage();
  77. }
  78. void MainWindow::loadLanguage()
  79. {
  80.     QTranslator translator;
  81.     bool b = false;
  82.     b = translator.load(":/Lan/cn");
  83.     qApp->installTranslator(&translator);
  84.     ui->radioButton_CN->setChecked(true);

  85.     // Method A: model dialog, translate is success in sub dialog
  86.     //lan.exec();
  87.     
  88.     // Method B: model dialog, translate is success in sub dialog
  89.     lan.show();
  90.     lan.raise();
  91.     lan.activateWindow();

  92. }
  93. void MainWindow::autoLoadLanguage()
  94. {
  95.     switch(m_lan_flag)
  96.     {
  97.     case LAN_CN:
  98.        //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
  99.          m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
  100.         break;
  101.     case LAN_EN:
  102.         m_translator.load(QString(":/Lan/en"));
  103.         break;
  104.     case LAN_DE:
  105.         m_translator.load(QString(":/Lan/de"));
  106.         break;
  107.     }
  108.     qApp->installTranslator(&m_translator);
  109.     lan.show();
  110.     lan.raise();
  111.     lan.activateWindow();

  112. }
  113. // Method 2: Use ChangeEvent to retranslateUi
  114. void MainWindow::changeEvent(QEvent *event)
  115. {
  116.     if(event->type() == QEvent::LanguageChange)
  117.         ui->retranslateUi(this);
  118.     else
  119.         QWidget::changeEvent(event);
  120. }



子窗口代码

点击(此处)折叠或打开

  1. #include "languagewidget.h"
  2. #include "ui_languagewidget.h"

  3. languageWidget::languageWidget(QDialog *parent) :
  4.     QDialog(parent),
  5.     ui(new Ui::languageWidget)
  6. {
  7.     ui->setupUi(this);
  8.     m_lan_flag = LAN_EN;
  9.     RefreshUI();
  10. }

  11. languageWidget::~languageWidget()
  12. {
  13.     delete ui;
  14. }

  15. void languageWidget::RefreshUI()
  16. {
  17.     ui->pushButton_CN->setText(tr("Chinese"));
  18.     ui->pushButton_EN->setText(tr("English"));
  19.     ui->pushButton_GE->setText(tr("Germen"));
  20.     setWindowTitle(tr("Form"));
  21. }

  22. void languageWidget::on_pushButton_EN_clicked()
  23. {
  24.     m_lan_flag = LAN_EN;
  25.     autoLoadLanguage();
  26. }

  27. void languageWidget::on_pushButton_CN_clicked()
  28. {
  29.     m_lan_flag = LAN_CN;
  30.     autoLoadLanguage();
  31. }

  32. void languageWidget::on_pushButton_GE_clicked()
  33. {
  34.     m_lan_flag = LAN_DE;
  35.     autoLoadLanguage();
  36. }
  37. void languageWidget::setlanguage(int language)
  38. {
  39.     m_lan_flag = language;
  40. }

  41. void languageWidget::autoLoadLanguage()
  42. {
  43.     switch(m_lan_flag)
  44.     {
  45.     case LAN_CN:
  46.        //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
  47.          m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
  48.         break;
  49.     case LAN_EN:
  50.         m_translator.load(QString(":/Lan/en"));
  51.         break;
  52.     case LAN_DE:
  53.         m_translator.load(QString(":/Lan/de"));
  54.         break;
  55.     }
  56.     qApp->installTranslator(&m_translator);
  57. }

  58. // Method 2: Use ChangeEvent to retranslateUi
  59. void languageWidget::changeEvent(QEvent *event)
  60. {
  61.     if(event->type() == QEvent::LanguageChange)
  62.         ui->retranslateUi(this);
  63.     else
  64.         QWidget::changeEvent(event);
  65. }

子窗口弹出



语言自动切换












本文转自:
http://blog.chinaunix.net/uid-20570485-id-4418782.html


  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt实现国际化和多语言切换需要以下步骤: 1. 在Qt项目中创建一个“ts”文件,用于存储翻译后的资源。可以使用Qt自带的工具“Qt Linguist”来创建和编辑这些文件。 2. 在Qt项目中使用Qt的翻译API来翻译界面元素。例如,使用tr()函数来标记需要翻译的字符串。 3. 使用lupdate工具来生成一个“.ts”文件,其中包含需要翻译的所有字符串。 4. 使用Qt Linguist编辑器来翻译这些字符串,并将它们保存到“.ts”文件中。 5. 使用lrelease工具来生成一个二进制的翻译文件“qm”文件,其中包含翻译后的资源。 6. 在Qt项目中加载这些翻译文件,并在运行时切换语言。 下面是一个简单的示例代码,演示如何在Qt实现语言切换: ```cpp #include <QApplication> #include <QTranslator> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 加载翻译文件 QTranslator translator; translator.load("myapp_zh.qm"); app.installTranslator(&translator); // 设置界面元素的翻译 QLabel label(tr("Hello World!")); label.show(); return app.exec(); } ``` 在上面的例子中,我们使用了QTranslator类来加载翻译文件,并使用installTranslator()函数将其安装到应用程序中。我们还使用了tr()函数来标记需要翻译的字符串。 当应用程序启动时,它将自动加载当前系统语言对应的翻译文件。如果用户切换语言,我们只需要重新加载对应的翻译文件即可。 希望这可以帮助你实现Qt中的国际化和多语言切换
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值