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的了,所以在翻译时也能看见。
点击(此处)折叠或打开
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_DE->setText(tr("Germen"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton->setText(tr("Switch"));
- ui->radioButton_CN->setText(tr("Chinese"));
- ui->radioButton_DE->setText(tr("Germen"));
- ui->radioButton_EN->setText(tr("English"));
- setWindowTitle(tr("MainWindow"));
建议:在程序中的字符串使用英文,汉语等通过多国语翻译来实现,而不要采取把汉字写在代码中。
2、在工程文件***.pro中,添加一项 TRANSLATIONS += ***.ts ****.ts 扩展名为.ts是翻译的源文件,表示生成这几个文件。一般我们会在命名中把区域加进去,更好的注释这些文件是用于什么语言的,比如中文大多会这样命名 myapp_zh_CN.ts, zh_CN表示的就是中国。
点击(此处)折叠或打开
- TRANSLATIONS+=cn.ts \
- de.ts \
- 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. 要求在程序运行过程中动态切换语言,需要
点击(此处)折叠或打开
- void MainWindow::loadLanguage()
- {
- QTranslator translator;
- bool b = false;
- b = translator.load(":/Lan/cn");
- qApp->installTranslator(&translator);
- ui->radioButton_CN->setChecked(true);
- RefreshUI();
- }
- void MainWindow::RefreshUI()
- {
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_DE->setText(tr("Germen"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton->setText(tr("Switch"));
- ui->radioButton_CN->setText(tr("Chinese"));
- ui->radioButton_DE->setText(tr("Germen"));
- ui->radioButton_EN->setText(tr("English"));
- setWindowTitle(tr("MainWindow"));
- }
点击(此处)折叠或打开
- void MainWindow::loadLanguage()
- {
- QTranslator translator;
- bool b = false;
- b = translator.load(":/Lan/cn");
- qApp->installTranslator(&translator);
- ui->radioButton_CN->setChecked(true);
- RefreshUI();
- }
- void MainWindow::RefreshUI()
- {
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_DE->setText(tr("Germen"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton->setText(tr("Switch"));
- ui->radioButton_CN->setText(tr("Chinese"));
- ui->radioButton_DE->setText(tr("Germen"));
- ui->radioButton_EN->setText(tr("English"));
- setWindowTitle(tr("MainWindow"));
- }
方法2:手动导入XXX.qm文件,通过ui文件,当调用qApp->installTranslator(&translator);时就会给ui文件发送的 QEvent :: LanguageChange 事件,通过调用ui->ui->retranslateUi()来更新tr("XXX")字段
需要说明的时, 一般我们使用设计器来设计 界面 UI,也就是程序源码中我们看到的 ***.ui文件,在载入翻译器后,我们应该调用 ui->retranslateUi() ,这个函数实际上就是把 界面 控件的text重新载入一遍,可以在 ui_***.cpp中看到该函数的实现。
点击(此处)折叠或打开
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- // Refresh();
- initial();
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- lan.close();
- }
- void MainWindow::initial()
- {
- m_lan_flag = LAN_EN;
- m_translator.load(":/Lan/en");
- ui->radioButton_EN->setChecked(true);
- qApp->installTranslator(&m_translator);
- RefreshUI();
- }
- void MainWindow::RefreshUI()
- {
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_DE->setText(tr("Germen"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton->setText(tr("Switch"));
- ui->radioButton_CN->setText(tr("Chinese"));
- ui->radioButton_DE->setText(tr("Germen"));
- ui->radioButton_EN->setText(tr("English"));
- setWindowTitle(tr("MainWindow"));
- }
- void MainWindow::on_pushButton_EN_clicked()
- {
- m_lan_flag = LAN_EN;
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_CN_clicked()
- {
- m_lan_flag = LAN_CN;
- // ui->radioButton_CN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_DE_clicked()
- {
- m_lan_flag = LAN_DE;
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_clicked()
- {
- // Method 1: Load language direct
- loadLanguage();
- // Method 2: Auto load language by QEvent::LanguageChange
- // autoLoadLanguage();
- }
- void MainWindow::on_radioButton_CN_clicked()
- {
- m_lan_flag = LAN_CN;
- ui->radioButton_CN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_radioButton_EN_clicked()
- {
- m_lan_flag = LAN_EN;
- ui->radioButton_EN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_radioButton_DE_clicked()
- {
- m_lan_flag = LAN_DE;
- ui->radioButton_DE->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::loadLanguage()
- {
- QTranslator translator;
- bool b = false;
- b = translator.load(":/Lan/cn");
- qApp->installTranslator(&translator);
- ui->radioButton_CN->setChecked(true);
- // Method A: model dialog, translate is success in sub dialog
- //lan.exec();
- // Method B: model dialog, translate is success in sub dialog
- lan.show();
- lan.raise();
- lan.activateWindow();
- }
- void MainWindow::autoLoadLanguage()
- {
- switch(m_lan_flag)
- {
- case LAN_CN:
- //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
- m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
- break;
- case LAN_EN:
- m_translator.load(QString(":/Lan/en"));
- break;
- case LAN_DE:
- m_translator.load(QString(":/Lan/de"));
- break;
- }
- qApp->installTranslator(&m_translator);
- }
- // Method 2: Use ChangeEvent to retranslateUi
- void MainWindow::changeEvent(QEvent *event)
- {
- if(event->type() == QEvent::LanguageChange)
- ui->retranslateUi(this);
- else
- QWidget::changeEvent(event);
- }
6,导入XXX.qm文件,
1) 可以通过XXX.qrc文件导入,但是通过XXX.qrc文件导入的话,每次qm文件有修改或更新,需要从新导入
2) 也可以通过相对或绝对路径指定。
点击(此处)折叠或打开
- case LAN_CN:
- //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;来确保整个翻译工作的正确性。
程序主要代码和运行效果
点击(此处)折叠或打开
- QT += core gui
- greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
- TARGET = LanguageChange
- TEMPLATE = app
- SOURCES += main.cpp\
- mainwindow.cpp \
- languagewidget.cpp
- HEADERS += mainwindow.h \
- languagewidget.h
- FORMS += mainwindow.ui \
- languagewidget.ui
- RESOURCES += lan.qrc
- TRANSLATIONS+=cn.ts \
- de.ts \
- en.ts
主窗口代码
点击(此处)折叠或打开
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- // Refresh();
- initial();
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- lan.close();
- }
- void MainWindow::initial()
- {
- m_lan_flag = LAN_EN;
- m_translator.load(":/Lan/en");
- ui->radioButton_EN->setChecked(true);
- qApp->installTranslator(&m_translator);
- RefreshUI();
- }
- void MainWindow::RefreshUI()
- {
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_DE->setText(tr("Germen"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton->setText(tr("Switch"));
- ui->radioButton_CN->setText(tr("Chinese"));
- ui->radioButton_DE->setText(tr("Germen"));
- ui->radioButton_EN->setText(tr("English"));
- setWindowTitle(tr("MainWindow"));
- }
- void MainWindow::on_pushButton_EN_clicked()
- {
- m_lan_flag = LAN_EN;
- ui->radioButton_EN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_CN_clicked()
- {
- m_lan_flag = LAN_CN;
- ui->radioButton_CN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_DE_clicked()
- {
- m_lan_flag = LAN_DE;
- ui->radioButton_DE->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_pushButton_clicked()
- {
- // Method 1: Load language direct
- //loadLanguage();
- // Method 2: Auto load language by QEvent::LanguageChange
- autoLoadLanguage();
- }
- void MainWindow::on_radioButton_CN_clicked()
- {
- m_lan_flag = LAN_CN;
- ui->radioButton_CN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_radioButton_EN_clicked()
- {
- m_lan_flag = LAN_EN;
- ui->radioButton_EN->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::on_radioButton_DE_clicked()
- {
- m_lan_flag = LAN_DE;
- ui->radioButton_DE->setChecked(true);
- autoLoadLanguage();
- }
- void MainWindow::loadLanguage()
- {
- QTranslator translator;
- bool b = false;
- b = translator.load(":/Lan/cn");
- qApp->installTranslator(&translator);
- ui->radioButton_CN->setChecked(true);
- // Method A: model dialog, translate is success in sub dialog
- //lan.exec();
- // Method B: model dialog, translate is success in sub dialog
- lan.show();
- lan.raise();
- lan.activateWindow();
- }
- void MainWindow::autoLoadLanguage()
- {
- switch(m_lan_flag)
- {
- case LAN_CN:
- //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
- m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
- break;
- case LAN_EN:
- m_translator.load(QString(":/Lan/en"));
- break;
- case LAN_DE:
- m_translator.load(QString(":/Lan/de"));
- break;
- }
- qApp->installTranslator(&m_translator);
- lan.show();
- lan.raise();
- lan.activateWindow();
- }
- // Method 2: Use ChangeEvent to retranslateUi
- void MainWindow::changeEvent(QEvent *event)
- {
- if(event->type() == QEvent::LanguageChange)
- ui->retranslateUi(this);
- else
- QWidget::changeEvent(event);
- }
子窗口代码
点击(此处)折叠或打开
- #include "languagewidget.h"
- #include "ui_languagewidget.h"
- languageWidget::languageWidget(QDialog *parent) :
- QDialog(parent),
- ui(new Ui::languageWidget)
- {
- ui->setupUi(this);
- m_lan_flag = LAN_EN;
- RefreshUI();
- }
- languageWidget::~languageWidget()
- {
- delete ui;
- }
- void languageWidget::RefreshUI()
- {
- ui->pushButton_CN->setText(tr("Chinese"));
- ui->pushButton_EN->setText(tr("English"));
- ui->pushButton_GE->setText(tr("Germen"));
- setWindowTitle(tr("Form"));
- }
- void languageWidget::on_pushButton_EN_clicked()
- {
- m_lan_flag = LAN_EN;
- autoLoadLanguage();
- }
- void languageWidget::on_pushButton_CN_clicked()
- {
- m_lan_flag = LAN_CN;
- autoLoadLanguage();
- }
- void languageWidget::on_pushButton_GE_clicked()
- {
- m_lan_flag = LAN_DE;
- autoLoadLanguage();
- }
- void languageWidget::setlanguage(int language)
- {
- m_lan_flag = language;
- }
- void languageWidget::autoLoadLanguage()
- {
- switch(m_lan_flag)
- {
- case LAN_CN:
- //m_translator.load(QString("../LanguageChange/Lan/cn")); // Use qm file by relative address
- m_translator.load(QString(":/Lan/cn")); // Use lan.qrc to load language
- break;
- case LAN_EN:
- m_translator.load(QString(":/Lan/en"));
- break;
- case LAN_DE:
- m_translator.load(QString(":/Lan/de"));
- break;
- }
- qApp->installTranslator(&m_translator);
- }
- // Method 2: Use ChangeEvent to retranslateUi
- void languageWidget::changeEvent(QEvent *event)
- {
- if(event->type() == QEvent::LanguageChange)
- ui->retranslateUi(this);
- else
- QWidget::changeEvent(event);
- }
子窗口弹出
语言自动切换
Qt多语言实现和动态切换(国际化)相关推荐
- QT实现多国语言的动态切换
摘要:本文论述了如何使用QT实现程序的多语系支持以及多语系的动态切换. 前沿 我们生活中用到的程序大多都是支持单一语言的,比如在中国我们用到的软件大多是汉语的,也有很少部分使用的是英语的,但是很少有软 ...
- QT 中英文切换-国际化(解决部分翻译不起作用的问题)
中英文切换-国际化 1.先看效果 2.核心代码(重新赋值刷新翻译文本) 2.0 pro文件配置 2.1 构造函数 2.2 两个按钮点击事件 3.翻译文件的生成与配置 4. 参考链接 1.先看效果 2. ...
- QML程序实现动态切换多语言
原文地址::https://zhuanlan.zhihu.com/p/40815590 Qt程序中实现多语言有Qt自己的一套机制,然而目前在5.9版本下该机制无法在程序运行期间动态切换语言.本文向大家 ...
- R语言plotly包可视化线图(line plot)、使用restyle参数自定义设置可视化结果中线条的颜色、使用按钮动态切换线条的颜色(change line color with button)
R语言plotly包可视化线图(line plot).使用restyle参数自定义设置可视化结果中线条的颜色.使用按钮动态切换线条的颜色(change line color with button i ...
- APP,实现多国语言动态切换
网上一个辅助类,找不到原博主文章链接,这里就直接贴出辅助类代码(自己再优化了一下).公司项目APP要支持13种语言,如下: 1.工具类 import android.content.Context; ...
- Android(国际化)多语言的实现和切换
1.直接创建 常用的values目录对应的国家和地区 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中文(香港):values-zh-rHK 英语(美国):va ...
- 用C语言画出动态的图片,Qt通过图片组绘制动态图片
本文实例为大家分享了Qt通过图片组绘制动态图片的具体代码,供大家参考,具体内容如下 任务实现: 通过定时器的使用来依次调用资源文件中的静态图片文件,从而达到是图片中内容动起来的效果: 效果实现: 实现 ...
- QT 多语言 字库 编码 文字方向相关问题
QT是支持多语言的,能够支持不同语言的动态切换,不同语言对应的编码格式转换,不同语言字体使用不同字库进行显示. 编码 QT对于字符串的处理使用了基本类型QString,它将所有传递给它的字符串或者字符 ...
- c语言增加动态分配的存储空间吗,C语言 关于内存动态分配问题
全局变量:分配到 内存的静态区. 局部变量(非静态):分配到 内存的动态区.在存储区中称为栈(stack) 临时数据(C允许内存动态分配区域):存放在自由空间区,称为堆区(heap) 内存动态分配 得 ...
最新文章
- angular轮播图
- 「后端小伙伴来学前端了」Element修改默认样式 | 记录自己学习前端踩坑日记
- 软件开发向大数据开发过渡_如何过渡到开发人员关系职业
- RHEL5.8系统裁减(内含做小Linux前的准备工作)
- 微信小程序开发实战——模块化
- CSS3实践之路(四):文本特效
- 1小时学会jQuery,全程无废话,直接上代码
- nbu备份oracle中途停止,NBU异构还原Oracle完整备份的一些总结
- 传感器系列之4.6雨滴传感器
- iphone 最具人气的论坛,网站,博客等
- 【操作系统】HRT任务和SRT任务(实时系统中的硬实时系统和软实时系统)
- tomcat启动成功并能运行项目,但无法显示那只小猫
- 内蒙古电大计算机考试成绩查询成绩查询,2021年网络教育7月统考成绩查询时间及入口...
- 【机器学习】常见问题
- 虚幻引擎 Unreal Engine 详细笔记 根据谌嘉诚视频无遗漏总结 快速上手
- apache默认端口号是多少
- 理解Play框架线程池
- 【ESD专题】ESD和EOS有什么差异?
- Socket 系统调用深入研究(TCP协议的整个通信过程)
- 艾永亮:打造超级产品,互联网公司的风水转到哪儿了?