目录
操作步骤
步骤:1.新建一个qt工程
2.在该工程的pro文件中添加(什么名字在什么路径下不影响)
TRANSLATIONS = lang_en.ts\
lang_zh.ts\
3.右键工程名,执行qmake。
第一种方法:工具---》外部---》qt语言家---》更新翻译,即可生成.ts文件(其实是个xml文件)。
第二种方法:在想要放ts文件的目录下,按住shift键,点击鼠标右键,选择在此处打开powershell窗口,执行“qt安装目录/bin/lupdate.exe xxx.pro文件”。
两种方式都会生成ts文件。
4.在qt安装目录的bin下打开qt linguist,或者在开始菜单中打开也行。点击文件---》打开---》把多个ts文件都选中打开。开始翻译。翻译结束ctrl+s保存。
第一种方法:再次点击文件----》发布全部。
第二种方法:在想要放qm文件的目录下,按住shift键,点击鼠标右键,选择在此处打
开powershell窗口,执行“qt安装目录/bin/lrelease.exe xxx.pro文件”。
两种方式都会生成qm文件。
5.点击qt左下角三角形运行即可。
编写代码注意事项
在main中写QTranslator代码 。
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//翻译程序
QTranslator translator;
translator.load("cn.qm");
app.installTranslator(&translator);
app.exec();
}
但是在main中像上面方式载入qm文件在实际项目开发过程中没有意义。因为在main中只能加载一个qm文件。如果你的界面只需要一种语言,直接在widget中设置好相应的语言文本就可以了。
所以写到widget中是较为合适的。
在widget中添加QComBoBox,在QComBoBox中添加多种语言。
#include <QApplication>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_translator = new QTranslator();
}
关键代码1:
connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));
关键代码2:
void changeLang(int)
{
if(m_translator != nullptr)
{
qApp->removeTranslator(m_translator);
}
bool flag = m_translator->load(langCode);
if(flag)
{
qDebug() << "load successful";
qApp->installTranslator(m_translator);
}
else
{
qDebug() << "load failed" ;
}
}
当你按照上述方式加载文件后,如果文件路径正确,会打印load successful。 但是你切换combobox时,发现你想翻译的文件内容没有发生改变。在main中改变qm文件,widget却可以更改成相应的语言。
什么原因呢?因为改变QComBoxBox时,界面已经初始化了。改变QComBoxBox对应的qm文件之后,会查找带有“tr”的地方。但是这个槽执行到installTranslator就结束了。找不到tr文本。
所以需要在installTranslator之后加类似以下代码(凡是你需要翻译的都要像以下代码一样加上)
ui->label->setText(tr("Hello World"));
ui->label_2->setText(tr("we"));
comboBox->setItemText(0, tr("English"));
comboBox->setItemText(1, tr("Chinese"));
在查找资料的过程中,发现有人写以下代码。
ui.retranslateUi(this);
只有label,button之类的是可以这么写的,点击button切换像手机的中英文切换。但是用到combobox时,使用这个就不行了。retranslateUi是ui文件生成的ui_xxx.h中的接口。该接口会将combobox先清空,然后按照你在构造中添加item的顺序重新添加item。导致的问题就是你选择第二个item,界面上永远显示第一个ltem。
容易疑惑点
网上资料有说加载的qm文件必须放在你翻译的界面前面。这句话对了一半。
1.qm文件可以在翻译的界面前面加载,但不是必须的。
2.qm文件也可以在翻译的界面里面加载。但需要加入刷新界面的语句。比如:
ui->label->setText(tr("Hello World"));
ui->label_2->setText(tr("we"));
comboBox->setItemText(0, tr("English"));
comboBox->setItemText(1, tr("Chinese"));
代码
widget文件证明了疑惑点中的第二个
secondForm文件证明了疑惑点中的第一个。
ui文件自己根据代码搞吧。
pro文件部分
.....
TRANSLATIONS = lang_en.ts\
lang_zh.ts\
lang_la.ts
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QComboBox>
#include <QTranslator>
#include "secondform.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void changeLang(int index);
private:
void createScreenLocal();
void changeTr(const QString& langCode);
void refreshLabel();
private:
Ui::Widget *ui;
QComboBox* combo;
static QTranslator * m_translator;
secondForm* m_secFormFo;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QApplication>
#include <QDebug>
#include <QVBoxLayout>
QTranslator * Widget::m_translator = nullptr;
//总共两个问题
//1.加载的qm文件必须放在你翻译的某个界面前面。
//2.假如你没放在前面,在本界面中载入,需要在载入文件之后加入刷新界面的语句。
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_translator = new QTranslator();
createScreenLocal();
}
Widget::~Widget()
{
delete ui;
}
void Widget::changeLang(int index)
{
QString langCode = QString("D:/project/Qt/translator1/");
if(index == 0)
{
langCode +="lang_en.qm";
}
else if(index == 1)
{
langCode +="lang_zh.qm";
}
else
{
langCode +="lang_la.qm";
}
changeTr(langCode);
refreshLabel();
m_secFormFo = new secondForm();
m_secFormFo->show();
}
void Widget::createScreenLocal()
{
combo = new QComboBox();
combo->addItem(tr("English"));
combo->addItem(tr("Chinese"));
combo->addItem(tr("Latin"));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(combo,1);
refreshLabel();
setLayout(layout);
connect(combo,SIGNAL(currentIndexChanged(int)),this,SLOT(changeLang(int)));
}
void Widget::changeTr(const QString &langCode)
{
if(m_translator != nullptr)
{
qApp->removeTranslator(m_translator);
}
bool flag = m_translator->load(langCode);
if(flag)
{
qDebug() << "load successful";
qDebug() << langCode;
qApp->installTranslator(m_translator);
}
else
{
qDebug() << "load failed" ;
}
}
void Widget::refreshLabel()
{
ui->label->setText(tr("Hello World"));
ui->label_2->setText(tr("we"));
combo->setItemText(0, tr("English"));
combo->setItemText(1, tr("Chinese"));
combo->setItemText(2, tr("Latin"));
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
secondForm.h
#ifndef SECONDFORM_H
#define SECONDFORM_H
#include <QWidget>
namespace Ui {
class secondForm;
}
class secondForm : public QWidget
{
Q_OBJECT
public:
explicit secondForm(QWidget *parent = 0);
~secondForm();
private:
Ui::secondForm *ui;
};
secondForm.cpp
#include "secondform.h"
#include "ui_secondform.h"
secondForm::secondForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::secondForm)
{
ui->setupUi(this);
}
secondForm::~secondForm()
{
delete ui;
}