热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Qt、QML动态语言切换功能的实现

    本例介绍了qt、qml混合编程的多语言翻译,工程目录及执行效果如下图:一、生成资源文件1.在pro中ti添加需要多语言翻译所需要的文件,这样编译工程时会自动生成这两个ts文

        本例介绍了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
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
#include
#include
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"< 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
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

 

 

 



推荐阅读
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • 在Kubernetes上部署JupyterHub的步骤和实验依赖
    本文介绍了在Kubernetes上部署JupyterHub的步骤和实验所需的依赖,包括安装Docker和K8s,使用kubeadm进行安装,以及更新下载的镜像等。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
author-avatar
绿林VS逍遥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有