本例介绍了qt、qml混合编程的多语言翻译,工程目录及执行效果如下图:
一、生成资源文件
1.在pro中ti添加需要多语言翻译所需要的文件,这样编译工程时会自动生成这两个ts文件。
TRANSLATIONS = language_zh_cn.ts \
language_en_us.ts
2.使用Qt Creator自带的工具生成ts文件
3.打开Qt Linguist工具(该工具在装Qt Creator一般默认是安装的),分别打开两个文件,进行翻译,保存(英文也可以不翻译)。
4.翻译完毕,运行步骤2中的第二个工具,将会由ts文件生成qm文件,这就是动态语言翻译所需要的资源文件。
二、动态加载资源文件
在下面这个例子中,Translator作为一个语言翻译类以单例的形式存在。
1.初始化
Translator.h
#ifndef TRANSLATOR_H
#define TRANSLATOR_H
#include <QObject>
class QTranslator;
class Translator : public QObject
{
Q_OBJECT
public:
static Translator* getInstance();
private:
explicit Translator(QObject *parent = 0);
~Translator();
signals:
void languageChanged();
public slots:
void loadLanguage(QString lang);
private:
QTranslator* m_translator;
};
#endif // TRANSLATOR_H
Translator.cpp
#include "Translator.h"
#include <QTranslator>
#include <QApplication>
#include <QDebug>
Translator *Translator::getInstance()
{
static Translator transInstance;
return &transInstance;
}
Translator::Translator(QObject *parent) : QObject(parent)
{
m_translator = new QTranslator;
}
Translator::~Translator()
{
delete m_translator;
}
void Translator::loadLanguage(QString lang)
{
qDebug()<<"load"<<lang;
if(NULL == m_translator)
{
return;
}
if(lang.contains("English"))
{
if(m_translator->load(":/language_en_us.qm"))
{
QApplication::installTranslator(m_translator);
emit languageChanged();
}
else
{
qDebug()<<"load en error";
}
}
else
{
if(m_translator->load(":/language_zh_cn.qm"))
{
QApplication::installTranslator(m_translator);
emit languageChanged();
}
else
{
qDebug()<<"load cn error";
}
}
}
main.c
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
Translator::getInstance()->loadLanguage("Chinese");//初始化为中文
MainWindow w;
w.show();
return a.exec();
}
2.QWidget添加动态翻译支持
步骤1只能支持静态设置,要想实现动态切换,需要在每个类中加入两个函数changEvent(QEvent *event)和translateUI(),
具体解释见代码标注:
maindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void changeEvent(QEvent* event);//用于动态翻译
void translateUI();//执行动态翻译
signals:
void sigSendPowerInitData(QString str);
void sigSendTimeInitData(QString str);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
void MainWindow::changeEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::LanguageChange:
translateUI();
break;
default:
QMainWindow::changeEvent(event);
break;
}
}
void MainWindow::translateUI()
{
ui->retranslateUi(this);
/*跳转到retranslateUi()函数,实际它执行了以下操作:重新设置了需要翻译的文本。
*在这个例子中ui是通过Qt Designer实现的,如果是自己new的部件也是同样的处理方法,重新设置本类中需要翻译的文本,qml文件中也是类似的处理
*
void retranslateUi(QMainWindow *MainWindow)
{
label->setText(QApplication::translate("MainWindow", "This is a label", Q_NULLPTR));
pushButton->setText(QApplication::translate("MainWindow", "Switch Language", Q_NULLPTR));
pushButton_2->setText(QApplication::translate("MainWindow", "Show QML Page", Q_NULLPTR));
}
*/
}
3.QML中添加动态翻译支持
类似c++中的做法,qml动态翻译的处理也是重新设置需要翻译的文本。
如上所述,Translator::loadLanguage()被调用时执行动态语言的加载,同时发出一个languageChanged()信号,该信号在下面被接收处理,从而完成动态加载。关于Connections以及混合编程的知识参考:
https://blog.csdn.net/ieearth/article/details/42243553
Connections
{
target: translator
onLanguageChanged:{
initTranslator();
}
}
function initTranslator(){
m_txt.text = qsTr("Power/w");
textChinese.text = qsTr("Chinese");
textEnglish.text = qsTr("English");
}
4.我们也可以在qml页面完成语言切换
这里是通过translator来调用loadLanguage(),加载语言文件后发出languageChanged()信号,从而触发qml页面的重新翻译。
Button{
id:btnEnglish
anchors.left: scaleLayout.right
anchors.leftMargin: 40
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -50
Text {
id : textEnglish
anchors.centerIn : btnEnglish
text: qsTr("English")
color: "white"
font.pointSize: fontButtonSize
}
onClicked: {
translator.loadLanguage("English");
}
style: buttonStyle
}
三、需要注意的几个点
1.QML上下文属性设置
//点击按钮弹出qml页面的操作
void MainWindow::on_pushButton_2_clicked()
{
QQuickWidget *quickWidget = new QQuickWidget();
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
quickWidget->setAttribute(Qt::WA_DeleteOnClose);
quickWidget->setClearColor(QColor(Qt::transparent));
//这里要注意:下面这个语句必须要在quickWidget->setSource()执行前执行,否则qml在加载的时候无法识别“translator”
quickWidget->rootContext()->setContextProperty("translator", Translator::getInstance());
quickWidget->setSource(QUrl(QStringLiteral("qrc:/PowerSetting.qml")));
//quickWidget->setWindowFlags(Qt::FramelessWindowHint);
quickWidget->show();
QQuickItem *item = quickWidget->rootObject();
//quickWidget->rootContext()->setContextProperty("translator", Translator::getInstance());//如果放在这里程序也能运行,但是会报错
//...
}
2.注意是每个需要翻译的页面都要添加changEvent(QEvent *event)和translateUI()函数处理。
3.每次改动文本后,需要重新生成ts和qm文件。
源码下载:https://download.csdn.net/download/zzwdkxx/10703708