qt中实现多语言功能
原理:
其本质就是生成ts文件,然后使用Linguist软件手工翻译,再生成qm文件,最后在主程序的开始加载不同的qm文件,实现多语言。
步骤:
修改程序文件
在pro文件中加入说明
TRANSLATIONS = lang_English.ts \
lang_Chinses.ts
目的就在在后面执行更新翻译(lupdate)命令在该目录位置生成.ts文件。前提条件是:该目录必须存在,上面的写法就是会在输出目录上生成lang_English.ts和lang_Chinses.ts。
语言文字在程序中说明
为了Qt识别你在程序中需要语言准换的文字,需要将需要转换的文字使用QObject::tr(“…”) 进行标记,否则程序中并不能对其进行识别。如
label->setText(tr( "Hello World"));
生成ts文件
在Qt的菜单栏之中选择:工具->外部->Qt预言家->更新翻译(lupdate)。这样在pro设置的TRANSLATIONS 目录下生成ts文件
Linguist翻译ts文件
Windows系统的msvc
点击电脑开始菜单,在出现的应用程序列表栏找到Qt安装文件夹,找到Linguist,选择适合自己的Linguist工具,双击打开。
linux系统
直接到qt的安装目录找到Linguist软件,如我的qt安装目录是/opt/Qt5.12.2/5.12.2/gcc_64/bin
打开Linguist后,点击文件->打开,在文件选择框中选择项目生成的ts文件,点击打开。会在Linguist中展示需要翻译的字符串,与类名。
在下方的翻译区进行手动翻译,第二栏是翻译的注释内容,可以不写注释。翻译完一项之后,用Ctrl+Enter会自动跳到下一个待翻译的字符串上,翻译完一个字符串之后,上图字符串列表前面的问号图标会变为一个绿色的对号。
备注:这里可以设置你想翻译成的语言。点击编辑-》翻译文本设置,会弹出一个对话框。在目标语言中选择需要的语言和国家/地区。
生成qm文件
ts文件翻译结束以后,点击保存。
然后在Qt Creator中,使用:工具->外部->Qt预言家->部署翻译(lrelease),就会生成需要的qm文件或者在Linguist中点击文件->发布。这样在和.ts文件同一目录下会生成.qm文件。
加载qm语言包
生成qm文件之后,在main.cpp文件中添加下面的代码,加载qm文件。一般将代码添加到QApplication a(argc, argv);下一行。
#include "dialog.h"
#include <QApplication>
#include <QTranslator>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTranslator translator;
QString runPath = QCoreApplication::applicationDirPath();
QString qmFilename = runPath + "/english_eg.qm";
bool bret = translator.load(qmFilename);
a.installTranslator(&translator);
Dialog w;
w.show();
return a.exec();
}
也可以通过点击按钮进行语言包切换设计。
void Dialog::on_pushButton_clicked()
{
QString qmFilename;
static QTranslator translator;
QString runPath = QCoreApplication::applicationDirPath(); //获取文件运行路径
qmFilename = runPath + "/english_eg.qm";
if (translator.load(qmFilename))
{
qApp->installTranslator(&translator);
}
ui->retranslateUi(this);//对整个ui界面所有控件都进行语言切换
}
- 重新设置界面显示
当实现“qApp->installTranslator(translator)”以后,还应该将显示界面重新显示一次进行更新。主界面可以直接借助步骤5中ui->retranslateUi(this)进行重新设置界面显示,但是这个只能更新当前页面,其余页面并不能直接显示出来,。需要对每个widget 对象重写虚函数virtual void changeEvent(QEvent *);
void Dialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type())
{
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
注释:
ui->retranslateUi(this);内部相当界面所有控件都调用setText。如下
ui->pushButton_2->setText(QApplication::translate(0,"中文", nullptr));
QApplication::translate函数的参数:第一个参数中0代表全局范围,第二个参数代表要转换语言的字符文本,即ts文件中的source资源。
所以关键是QApplication::translate函数。
TS文件格式
1、文件头部信息。指定了翻译文件的版本(2.1),目标语言(zh_CN,即中文)等信息。
2、划分的作用域名字。
3、每个待翻译的字符串都有一个 message 元素,其中location元素指定了源代码中字符串的位置;source 元素包含了原始的文本;translation元素用于存储翻译后的文本。
其中,location没有也可以,只是QT语言家打开.ts文件时定位不到字符串位置而已,主要还是source 元素和translation元素,source元素相当于字符串的id,翻译家通过source在lang_zh_CN.ts找中文文本,在lang_en.ts找英文文本。
如下面自定义的ts文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en_US">
<context>
<message>
<source>测试</source>
<translation>test</translation>
</message>
<message>
<source>中文</source>
<translation>chinese</translation>
</message>
<message>
<source>英文</source>
<translation>english</translation>
</message>
</context>
</TS>
代码实现语言切换
if(nLanguage == Enum_Language::Lang_en)
{
QString strLanguageFile = g_strRunPath + "/language/lang_en.qm";
QFile file(strLanguageFile);
bool bExist = file.exists();
if(!bExist)
{
return ;
}
static QTranslator translator;
if (translator.load(strLanguageFile))
{
qApp->installTranslator(&translator);
QString strMessage =”英文”;
const char* cStrMsg = strMessage.toStdString().c_str();
strMessage = QApplication::translate(0,cStrMsg, nullptr);
}
}