1 实现效果
简单的实现按钮的中英文和繁体字的切换
qt动态语言切换
2 实现步骤
1.生成ts翻译文件
(1)在pro文件中填写以下语句添加对应的翻译文件,根据自己需要翻译的语言添加
TRANSLATIONS += lang_zh_EN.ts\
lang_zh_CN.ts\
lang_zh_TW.ts
(2)然后使用以下工具生成对应翻译文件
2.生成qm文件
使用qt自带的工具编辑翻译文件,编辑完成之后,使用上图的工具的Irelease发布翻译,生成qm文件。
注意:只需要填写红框里面的就行了,如果下面也填写的话,只有碰到填写的内容才翻译,就比如我填写了”“繁体”两个字,如果此时已经翻译成英文“Traditional Chinese”,再想翻译成其他语言就无法切换了。
使用工具生成以下qm文件,然后手动添加到资源文件中
3.实现代码
具体的实现代码如下图所示
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTranslator>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
btns = new QButtonGroup(this);
btns->addButton(ui->btn_jianti,SYSTEM_LANGUAGE_SIMPLIFIED_CHINESE);
btns->addButton(ui->btn_fanti,SYSTEM_LANGUAGE_TRADITIONAL_CHINESE);
btns->addButton(ui->btn_eng,SYSTEM_LANGUAGE_ENGLISH);
connect(btns,SIGNAL(buttonClicked(int)),this,SLOT(slot_btnsClicked(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slot_btnsClicked(int id)
{
QString qmFilename;
switch (id) {
case SYSTEM_LANGUAGE_SIMPLIFIED_CHINESE:
qmFilename = ":/lang_zh_CN.qm";
break;
case SYSTEM_LANGUAGE_TRADITIONAL_CHINESE:
qmFilename = ":/lang_zh_TW.qm";
break;
case SYSTEM_LANGUAGE_ENGLISH:
qmFilename = ":/lang_zh_EN.qm";
break;
default:
break;
}
// 加载翻译文件
QTranslator* translator = new QTranslator(this);
translator->load(qmFilename);
qApp->installTranslator(translator);
// 重新设置界面显示
ui->retranslateUi(this);
}
以上代码中,语句ui->retranslateUi(this);是对UI文件的控件进行翻译。在生成的编译文件中可以看得到。
编译生成的代码如下图所示
所以,在使用中,调用这个函数可以对对应的控件文字进行翻译,但是同样的,如果这个控件的文字变化了呢?如果我的控件不是编写在UI文件中的,是使用代码new出来的对象呢?这些动态的情况,则需要程序员编写自己的翻译函数。在使用过程中我遇见的问题和解决方法请看第三节。
3 注意事项
- 1.对于UI文件中的控件,文字发生了变化,此时会有一个问题,调用retranslateUi(),此时控件的文字会翻译回原本的文字(字符已经编译生成,不会随着而变化),所以需要我们手动设置。此时最好不要调用retranslateUi()函数,不然那个控件的文字会变回去。同样的,对于用代码new出来的对象也要用这个方法来使用,并且对应字符串都使用tr()函数。
void MainWindow::changeEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::LanguageChange:
{
//ui->btn_test1->setText(tr("法语")); //文字固定可以这样,不固定调用下面的语句
ui->btn_test1->setText(tr(ui->btn_test1->text().toStdString().c_str()));
}
default:
break;
}
}
- 2.针对多界面,我的建议是每一个界面都要重写changeEvent(QEvent *event)函数,一来因为ui->retranslateUi(this);仅仅是针对本UI而已,对于子UI并没有调用,所以会导致可能没有翻译过来;二是因为具体界面的细节不一样,切控件也不尽相同,不能一概而论的直接调用如以下函数的内容。当然,如果界面不多变,当然是什么简单就使用什么。
QList<QLabel*> lb_list = this->findChildren<QLabel*>();
for(int i = 0;i<lb_list.size();i++)
{
lb_list.at(i)->setText(tr(lb_list.at(i)->text().toStdString().c_str()));
}
- 3.对于一些暂时没有使用在控件上,又或者是外部线程传进来的文字(有固定的情况),可以现在对应文件中使用如以下代码,将文字翻译添加到文件中,到使用时记得使用tr()函数,否则如果仅仅只是setText(name)的QString的话,也是不会翻译的。
QStringList warnList;
warnList<<tr("录制异常")<<tr("推流异常")<<<<tr("录制子码流异常");