实现QT的多语言切换(静态+动态)

背景:

1.项目开发上:多人多模块同时开发,需要考虑如何便于管理共同开发
2.文本有两类:界面上固定不变的文本(静态);在程序运行时才能获得的文本(动态)

任务:

实现软件的多语言切换功能。

接下来会介绍两个实现途径,分别是QT语言家工具,以及.ts文件的手动编写(推荐第二种)。

一、QT语言家

Qt Linguist(Qt 语言家)是 Qt 开发环境中用于国际化和本地化的工具。它会提供翻译支持,将应用程序的用户界面和其他文本元素翻译成不同的语言,是一种可视化工具。
如果安装了的话,可以在这里找到:
在这里插入图片描述

1、.pro文件增加TRANSLATIONS

TRANSLATIONS += resource/language/lang_zh_CN.ts\resource/language/lang_en.ts
说明:
lang_zh_CN.ts为中文部分,lang_en.ts为英文部分,
此处我的这两个.ts文件是放在resource/language目录下,需要照自己的具体路径进行更改

2、更新翻译(lupdate)

在这里插入图片描述
之后出现信息:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/785b8e7374ce4cff967c760b18cc03e8.pn

3、通过QT语言家打开.ts文件

在这里插入图片描述
由于我使用的是MSVC 2017 64-bit,所以我是使用对应的Linguist打开两个.ts文件:
在这里插入图片描述

在这里插入图片描述
在这两项中分别写入英文文本和中文文本,编辑完成后保存并发布(lrelease):
在这里插入图片描述
发布(lrelease)的目的是将.ts文件编译为.qm文件,.qm文件是二进制文件,可以看到同目录下已经生成.qm文件:
在这里插入图片描述

4、代码中使用.qm文件进行翻译

将生成的.qm文件加入到资源文件中。
在启动时根据不同的系统语言显示不同的翻译:

void MainWindow::initLanguage()
{QTranslator translator;QLocale::Language lab = QLocale::system().language();if(QLocale::Chinese == lab){translator.load(":/language/lang_zh_CN.qm");hApp->installTranslator(&translator);Q_EMIT hApp->m_sigmanager->translateLanguage(LANGUAGE::CHINESE);}else if(QLocale::English== lab){translator.load(":/language/lang_en.qm");hApp->installTranslator(&translator);Q_EMIT hApp->m_sigmanager->translateLanguage(LANGUAGE::ENGLISH);}
}说明:
注意.qm文件的路径要写对,不然无法翻译,如果找不到可以在.pro文件中增加 INCLUDEPATH
这里我自定义了translateLanguage信号去触发语言的切换,各个模块负责分别连接该信号,编写槽函数,举例:
某模块:
connect(hApp->m_sigmanager,&SignalManager::translateLanguage,this,&SampleMainWidget::retranslate);
void SampleMainWidget::retranslate()
{ui->retranslateUi(this);
}

5、需要注意的问题

QT语言家不止可以展示.ui文件中我们给控件预先编辑的文本内容,还有代码中定义的文本内容,只是需要在QT语言家展示代码内待翻译文本,要使用宏 QT_TR_NOOP ,它通常用于标记那些在运行时不需要翻译,但需要在翻译文件中保留的字符串。

QString test = QT_TR_NOOP("test1")说明:
test的值仍然是原文本,而非翻译后的文本

在需要翻译时,使用以下方式(在retranslateui后需要重新设置控件文本):

void SampleMainWidget::retranslate()
{ui->retranslateUi(this);QString text = ui->rackBtn->text();ui->rackBtn->setText(hApp->translate("SampleApply",text.toStdString().c_str()));
}
说明:
hApp->translate中的第一个参数,其实对应.ts文件中的<name>元素,和作用域的作用类似
如果使用QT语言家,一般是QT_TR_NOOP定义文本所在的类名
第二个参数,其实对应.ts文件中的<source>元素,这里的类型是char*

二、.ts文件的手动编写

首先需要简单了解.ts文件和.qm文件:

  • .ts文件(翻译源文件):.ts文件是Qt中的翻译源文件,XML格式。它包含了源代码中的所有可翻译文本,以及它们的上下文信息。

  • .qm文件(翻译目标文件):.qm文件是Qt中的翻译目标文件,二进制格式。.qm文件包含了已经翻译好的文本,以及与之对应的源代码中的文本。通过将.ts文件编译成.qm文件,可以提高程序的执行效率,因为程序在运行时直接加载.qm文件,而无需解析和处理XML格式的.ts文件。

1、.ts的格式说明

打开.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找英文文本。

2、多人管理开发

创建language.xlsx,language.xlsx中包含多个模块sheet,每个sheet的表头为 id Chinese English
其中id为文本项唯一标识符,Chinese为中文文本,English为英文文本。
在这里插入图片描述
使用python,将excel转换为.ts文件,并编译为.qm文件:

import openpyxl
import subprocess
from xml.dom.minidom import Documentdef read_excel(file_path):# 打开 Excel 文件wb = openpyxl.load_workbook(file_path)# 读取所有 sheet 的数据all_rows = []for sheet_name in wb.sheetnames:sheet = wb[sheet_name]all_rows.extend([tuple(sheet.cell(row=row, column=col).value for col in range(1, sheet.max_column + 1))for row in range(2, sheet.max_row + 1)])return all_rowsdef create_ts_file(language, rows):# 创建 XML 文档doc = Document()ts = doc.createElement('TS')ts.setAttribute('version', '2.1')ts.setAttribute('language', language)doc.appendChild(ts)# 创建 <context> 元素context = doc.createElement('context')ts.appendChild(context)for row in rows:source, chinese, english = row# 创建 <message> 元素message = doc.createElement('message')# 创建 <source> 元素source_element = doc.createElement('source')source_element.appendChild(doc.createTextNode(source))message.appendChild(source_element)# 创建 <translation> 元素translation_element = doc.createElement('translation')translation_element.appendChild(doc.createTextNode(chinese if language == 'zh_CN' else english))message.appendChild(translation_element)context.appendChild(message)# 将 XML 写入文件,设置缩进和换行xml_str = doc.toprettyxml(indent="    ", encoding='utf-8').decode('utf-8')ts_file_path = f'lang_{language}.ts'with open(ts_file_path, 'w', encoding='utf-8') as file:file.write(xml_str)# 调用 lrelease 命令编译 .ts 文件为 .qm 文件subprocess.run(['lrelease', ts_file_path])if __name__ == "__main__":# 读取 Excel 文件数据excel_data = read_excel("language.xlsx")for language in ["zh_CN", "en"]:# 生成每个语言的 .ts 文件create_ts_file(language, excel_data)

以下为生成的内容格式:
在这里插入图片描述
思路:
将工程所有文本都集中在一个excel中,需要给专业翻译人员翻译时,只需要提供这样一份excel,在指定位置补充翻译后文本就可以。
这里是简单通过id的数值范围使各模块独立,即每个sheet的文本容量为1万,从左到右:main(0到9999),scheme(10000到19999),sample(20000到29999)…以此类推。
也可以通过sheet名称作为作用域名称,在.ts文件中增加name元素,只要能保证source唯一不重复,这些方式都是可以的。

3、代码中如何使用

在代码中的使用(可以不使用ui->retranslateUi(this);了):
在连接语言切换信号的槽函数中设置待翻译的文本信息,如:

void SampleMainWidget::retranslate()
{ui->rackBtn->setText(hApp->translate(0,"0_main_voice"));
}

translate参数中0代表全局范围,"0_main_voice"即文本id。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2661639.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】vector 基本使用(详解)

目录 一&#xff0c;vector 的介绍 二&#xff0c;vector 的定义 1&#xff0c;vector() 2&#xff0c;vector&#xff08;size_type n, const value_type& val value_type()&#xff09; 3&#xff0c;vector (const vector& x) 4&#xff0c;vector (InputIte…

使用 sourcetree 的《遴选》功能

假设你有一个分支&#xff0c;有两个提交 A&#xff0c;和B&#xff0c;你现在想在A提交的基础上把 B提交的功能做修改&#xff0c;你可以使用 遴选功能。 在A 提交的基础上新建一个分支&#xff0c;然后在B提交上面&#xff0c;右键&#xff0c;选择 遴选&#xff0c;那么B修改…

传感器原理与应用复习--磁电式与霍尔传感器

文章目录 上一篇磁电感应传感器工作原理应用 霍尔传感器工作原理基本特性应用 下一篇 上一篇 传感器原理与应用复习–电容式与压电式传感器 磁电感应传感器 工作原理 导体在稳恒均匀磁场中&#xff0c;沿垂直磁场方向运动时&#xff0c;产生的感应电势为 e B l v e Blv …

Mediapipe绘制实时3d铰接骨架图——Mediapipe实时姿态估计

一、前言 大约两年前&#xff0c;基于自己的理解我曾写了几篇关于Mediapipe的文章&#xff0c;似乎帮助到了一些人。这两年&#xff0c;忙于比赛、实习、毕业、工作和考研。上篇文章已经是一年多前发的了。这段时间收到很多私信和评论&#xff0c;请原谅无法一一回复了。我将尝…

7+WGCNA+机器学习+泛癌生信思路,非肿瘤也能结合泛癌分析

今天给同学们分享一篇生信文章“Analysis and Experimental Validation of Rheumatoid Arthritis Innate Immunity Gene CYFIP2 and Pan-Cancer”&#xff0c;这篇文章发表在Front Immunol期刊上&#xff0c;影响因子为7.3。 结果解读&#xff1a; DEG筛选和数据预处理 数据在…

Baumer工业相机堡盟相机如何使用NEOAPI SDK实现相机的连接(C++)

Baumer工业相机堡盟相机如何使用NEOAPI SDK实现相机的连接&#xff08;C&#xff09; Baumer工业相机Baumer工业相机SDK技术背景代码分析第一步&#xff1a;先使用NEOAPI函数查找相机第二步&#xff1a;连接相机后对相机进行采图第三步&#xff1a;将采集的图像显示在UI界面上 …

BUG-由浏览器缩放引起PC端显示手机端视图

文章目录 来源解决 来源 启动Vue项目&#xff0c;用浏览器打开显示手机端视图&#xff0c;从vscode直接ctrl链接打开正常显示。 检查-未开启仿真&#xff0c;但仍显示错误。 解决 浏览器缩放问题。 修改为100%

【UE5.1】程序化生成Nanite植被

目录 效果 步骤 一、下载Gaea软件和树林资产 二、使用Gaea生成贴图 三、 生成地形 四、生成草地 五、生成树林 六、生成湖泊 七、其它功能介绍 7.1 调整树林生成的面积 7.2 让植物随风飘动 7.3 玩家和植物互动 7.4 雪中树林 7.5 环境音效 效果 步骤 一、下载Ga…

Android 13 默认关闭 快速打开相机

介绍 在设置菜单的手势界面里&#xff0c;快速打开相机是默认开启的&#xff0c;此功能当开启时连续点击两次电源键会打开相机&#xff0c;现在客户需要默认关闭。 效果展示 修改 这里一开始想到的就是配置文件&#xff0c;在路径下果然找到了,从注释中看使我们需要的&#x…

CTF-Crypto练习

技能兴鲁初赛 from gmpy2 import * from Crypto.Util.number import *flag flag{I\m not gonna tell you the FLAG} # 这个肯定不是FLAG了&#xff0c;不要交这个咯p getPrime(2048) q getPrime(2048) m1 bytes_to_long(bytes(flag.encode()))e1 3247473589 e2 3698409…

【验证概括 SV的数据类型_2023.12.18】

验证概括 验证的过程是保证芯片实现符合规格说明书&#xff08;Specification&#xff0c;spec&#xff09;的过程 验证的两项任务&#xff1a; RTL sim&#xff1a;前仿真&#xff0c;验证功能 GLS-Gate (Level Simulation)&#xff1a;后仿真&#xff0c;验证功能和时序 验…

【小白专用】C# 压缩文件 ICSharpCode.SharpZipLib.dll效果:

插件描述&#xff1a; ICSharpCode.SharpZipLib.dll 是一个完全由c#编写的Zip, GZip、Tar 、 BZip2 类库,可以方便地支持这几种格式的压缩解压缩, SharpZipLib 的许可是经过修改的GPL&#xff0c;底线是允许用在不开源商业软件中&#xff0c;意思就是免费使用。具体可访问ICSha…

svg学习

概念 svg 可缩放矢量图形 svg 使用xml格式定义图像 svg 形状 矩形 <rect> <?xml version"1.0" standalone"no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd&q…

polar CTF上传

WEB-上传 一、查看题目信息 二、漏洞分析 经过上传测试发现&#xff0c;这题过滤掉了<?&#xff0c;这样正常的一句话木马就没法上传&#xff0c;这里可以用utf-16编码绕过。因为utf-16占utf-8的两倍长度&#xff0c;上传时默认检测为utf-8,从而就能绕过检测成功上传。 同…

Paper Survey——NeRF SLAM

NeRF SLAM&#xff08;Neural Radiance Fields Simultaneous Localization and Mapping&#xff09;是一种结合神经辐射场&#xff08;NeRF&#xff09;和SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;的先进技术&#xff0c;用于实时地构建三维环境地图…

redis 从0到1完整学习 (十一):RedisObject 之 String 类型

文章目录 1. 引言2. redis 源码下载3. redisObject 管理 String 类型的数据结构4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&#xff09;&#xff1a;…

ERROR: No matching distribution found for torch==1.12.0+cu113

原因 pip install torch1.12.0cu113用pip安装torch时&#xff0c;出现&#xff1a; ERROR: No matching distribution found for torch1.12.0cu113好像不少用清华源的会出现这个问题 解决办法 pytorch官网&#xff1a;https://pytorch.org/get-started/previous-versions/ …

certum的ip证书购买流程

Certum是成立于欧洲的CA认证机构&#xff0c;经过二十几年的发展Certum已经成为欧洲知名的CA认证机构之一&#xff0c;拥有广泛的客户群体和合作伙伴。IP证书是Certum为只有公网IP地址的网站准备的数字加密服务。今天就随SSL盾小编了解购买Certum旗下的IP证书流程。 第一步&am…

分享72个NodeJs项目源码总有一个是你想要的

分享72个NodeJs项目源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1_bzxbmBlN8ga4-Ci1I0-0w?pwd6666 提取码&#xff1a;6666 项目名称 A lottery webapp …

惟客数据昆仑-开发云成功开源了!让研发更简单高效

​近期&#xff0c;WakeData惟客数据产品——昆仑-开发云成功开源。 今年4月&#xff0c;惟客数据完成了新一轮产品能力升级&#xff0c;与战略伙伴联合研发具有私有化部署能力的行业大模型 WakeMind 。 昆仑-开发云在可视化领域建模的基础上也引入了 WakeMind 的能力&#x…