QT/QML国际化:中英文界面切换显示(cmake方式使用)
目录
前言
实现步骤
1. 准备翻译文件
2. 翻译字符串
3.设置应用程序语言
cmake 构建方式
示例代码
总结
1. 使用 file(GLOB ...)
2. 引入其他资源文件
再次生成翻译文件
5. 手动更新和生成.qm文件
其他资源
前言
在当今全球化的软件开发环境中,应用程序的国际化(i18n)与本地化(l10n)能力已成为衡量其专业度和用户体验的重要标准之一。QT/QML作为一套强大的跨平台应用程序开发框架,其内置的国际化支持机制使得开发者能够轻松地为应用添加多语言功能,从而满足不同地域用户的语言需求。本文将深入探讨如何在QT/QML项目中实现中英文显示的国际化,从基础概念到具体实施步骤,帮助开发者构建出更加友好、包容的应用界面。
QT框架提供了完整的国际化支持,包括字符串提取、翻译文件的创建与管理、以及运行时的动态加载等。QML作为QT用于构建用户界面的声明式语言,也完全融入了这一国际化体系,让开发者能以简洁高效的方式实现界面的多语言切换。
实现步骤
在QT/QML应用中实现国际化(i18n)以支持中英文显示,主要涉及以下几个步骤:
1. 准备翻译文件
创建翻译文件:使用Qt Linguist工具(QT自带的工具)或手动创建.ts(Translation Source)文件。通常为每种语言创建一个,例如en.ts用于英语,zh.ts用于中文。
提取字符串:使用lupdate工具从源代码中提取可翻译的字符串到.ts文件中。这包括QML文件中的qsTr()或qsTranslate()包裹的文本。
2. 翻译字符串
翻译.ts文件:使用Qt Linguist工具(QT自带)或其他翻译工具编辑.ts文件,将英文字符串翻译成目标语言(如中文)。
编译.ts文件为.qm:使用lrelease工具将翻译好的.ts文件编译为二进制的.qm(Qt Message File)文件,这是运行时加载的文件。
3.设置应用程序语言
动态切换语言:可以通过修改QLocale或直接设置Application的语言来改变界面语言。
cmake 构建方式
生成Qt的ts翻译文件,编辑CMakeLists.txt文件,使用qt5_create_translation。
# 设置翻译源文件(.ts)的输出目录
#set(QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/main.qml)
# 使用 file(GLOB ...) 获取所有 QML 文件
file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml)
set(TS_FILES${CMAKE_CURRENT_BINARY_DIR}/translations/daemon_en_US.ts${CMAKE_CURRENT_BINARY_DIR}/translations/daemon_zh_CN.ts)# 关键
find_package(Qt5LinguistTools)
qt5_create_translation(QM_FILES ${QML_FILES} ${TS_FILES} OPTIONS -source-language en_US -no-obsolete)# 添加可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES})
注意,必须将 ${QM_FILES}加入到add_executable参数中才能在编译时生成只有原文的ts文件
ts文件会在“清除”或重新编译的时候一并被删除,再编译的时候生成全新的ts(原有的翻译会丢失,万分注意!!)
示例代码
假设您的 C++ 代码如下:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTranslator>
#include <QLocale>
#include <QQmlContext>int main(int argc, char *argv[])
{QGuiApplication app(argc, argv);// 创建翻译器对象QTranslator translator;// 初始化加载翻译文件(默认载入英文)translator.load(":/translations/daemon_en_US.qm");app.installTranslator(&translator);QQmlApplicationEngine engine;// 将翻译器对象设置到 QML 上下文环境中engine.rootContext()->setContextProperty("translator", &translator);engine.load(QUrl(QStringLiteral("qrc:/source/qml/main.qml")));return app.exec();
}
在 QML 文件中,假设您有如下内容:
import QtQuick 2.12
import QtQuick.Controls 2.12ApplicationWindow {visible: truewidth: 640height: 480title: qsTr("Hello World")Column {anchors.centerIn: parentspacing: 20Text {id: labeltext: qsTr("This is a text")}Button {text: "Switch to Chinese"onClicked: {// 动态切换到中文if (translator.load(":/translations/daemon_zh_CN.qm")) {Qt.application.installTranslator(translator);label.text = qsTr("This is a text"); // 触发翻译更新}}}Button {text: "Switch to English"onClicked: {// 动态切换到英文if (translator.load(":/translations/daemon_en_US.qm")) {Qt.application.installTranslator(translator);label.text = qsTr("This is a text"); // 触发翻译更新}}}}
}
在这个例子中,通过 engine.rootContext()->setContextProperty("translator", &translator); 这一行代码,QML 中的 translator 对象和 C++ 中的翻译器对象关联起来,使得 QML 中能够调用 C++ 的方法来动态加载翻译文件并自动更新界面显示的语言。
总结
通过将翻译器对象设置为 QML 上下文的属性,可以在 QML 中调用 translator 对象的函数,实现动态加载和切换翻译文件的功能,从而满足多语言动态切换的需求。
其中 engine.rootContext()->setContextProperty("translator", &translator); 的主要作用是将 C++ 对象暴露给 QML,以便在 QML 中直接使用和操控这个对象,使得多语言支持更具灵活性和动态性。
以下是一个将QML文件夹下的所有QML文件引入到CMakeLists.txt中的方法:
1. 使用 file(GLOB ...)
file(GLOB ...) 可以递归地获取指定目录下的所有符合条件的文件。这种方法非常灵活,适用于需要引入一组文件的场景。
cmake_minimum_required(VERSION 3.12)project(daemon VERSION 1.0)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)find_package(Qt5 COMPONENTS Core Quick LinguistTools REQUIRED)# 设置源文件和头文件
set(SOURCESmain.cppsource/cpp/myclass.cpp
)set(HEADERSsource/cpp/myclass.h
)# 使用 file(GLOB ...) 获取所有 QML 文件
file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml)# 设置翻译文件
set(TS_FILES${CMAKE_CURRENT_SOURCE_DIR}/translations/daemon_en_US.ts${CMAKE_CURRENT_SOURCE_DIR}/translations/daemon_zh_CN.ts
)# 创建翻译文件
qt5_create_translation(QM_FILES TS_FILES ${TS_FILES} QML_FILES ${QML_FILES})# 添加可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES})# 链接Qt库
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick)
在这个示例中:
file(GLOB_RECURSE QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/qml/*.qml):这一步使用通配符*.qml来递归获取source/qml目录下的所有QML文件,并将结果存储到QML_FILES变量中。- 剩余的CMake配置保留了引入其他源文件和头文件,以及Qt翻译文件的生成和处理。
2. 引入其他资源文件
如果您的QML项目中还有其他类型的资源文件(如图像文件、.js文件等),也可以使用类似的方法引入:
# 引入图像资源文件
file(GLOB_RECURSE IMAGE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/images/*)# 引入JavaScript文件
file(GLOB_RECURSE JS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/js/*.js)
将这些文件添加到目标中:
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${QML_FILES} ${QM_FILES} ${IMAGE_FILES} ${JS_FILES})
通过这种方式,可以灵活地管理和组织项目中的各种资源文件,简化CMake配置,确保正确引入所有需要的文件。
再次生成翻译文件
确保您的.ts文件已正确配置并包含在项目中。尝试手动运行lupdate命令并查看输出:
cd path_to_your_project
lupdate source/qml/*.qml source/cpp/*.cpp -ts translations/daemon_en_US.ts translations/daemon_zh_CN.ts
然后使用linguist工具打开.ts文件,确认其中是否包含待翻译文本:
linguist translations/daemon_zh_CN.ts
5. 手动更新和生成.qm文件
如果依旧遇到问题,可以尝试手动更新ts文件并生成qm文件,以确保流程正确:
# 手动更新 TS 文件
lupdate source/qml/*.qml source/cpp/*.cpp -ts translations/daemon_en_US.ts translations/daemon_zh_CN.ts# 使用Qt Linguist工具编辑并保存 TS 文件
linguist translations/daemon_en_US.ts
linguist translations/daemon_zh_CN.ts# 手动生成 QM 文件
lrelease translations/daemon_en_US.ts
lrelease translations/daemon_zh_CN.ts
在以上步骤中,验证所有QML和C++文件中确实包含带有qsTr()或tr()的翻译标记,并确认lupdate和lrelease工具的路径和执行是否正确。如果所有步骤正确完成,生成的.qm文件会包含预期的翻译数据。
注意:
lupdate工具本身不会自动进行翻译。它的主要功能是从源代码和QML文件中提取出所有标记为需要翻译的字符串,并生成或更新.ts文件。这些.ts文件是XML格式的翻译源文件,其中包含了需要翻译的原始字符串及其上下文信息,但并不会包含任何自动生成的翻译。
生成的.ts文件中所有翻译项最初都是未翻译状态,开发人员或翻译人员需要手动使用Qt Linguist工具为每个字符串提供翻译。
对于QML中的文本,应该使用qsTr()函数来包裹那些需要翻译的字符串。例如:
Text {text: qsTr("Hello, World!")}
在C++代码中,你应该使用tr()宏来标记需要翻译的字符串。例如:
QString message = tr("Welcome to the application.");
确保所有的用户可见的字符串都通过tr()进行了包裹。这包括但不限于对话框消息、菜单项、按钮标签等。
避免在代码逻辑中使用硬编码的字符串:无论是QML还是C++,都应该避免直接在逻辑处理中使用未经qsTr()或tr()处理的字符串。如果字符串中包含变量或需要格式化的地方,使用占位符(如C++中的arg()方法或QML中的字符串插值)并确保翻译时考虑这些变量的存在。
qsTr()和tr()是分别在QML和C++中进行国际化的基本手段,通过它们确保字符串可以被翻译工具识别并处理。
总结:
lupdate提取源字符串并生成.ts文件,不会自动翻译。- 使用
linguist工具手动翻译.ts文件内容。 - 使用
lrelease生成.qm文件以供应用程序使用。
通过这个流程,您可以管理和使用Qt项目中的翻译文件,实现应用程序的多语言支持。
其他资源
https://www.cnblogs.com/Paoyao/p/15752116.html
https://zhuanlan.zhihu.com/p/379477970
配置CLion管理Qt项目国际化支持的方法_C 语言_脚本之家
Qt之Qml 国际化—实现简易语言切换功能_qml 中英文切换-CSDN博客
Qt / Qml 中支持多国语言_qml 多语言-CSDN博客
相关文章:
QT/QML国际化:中英文界面切换显示(cmake方式使用)
目录 前言 实现步骤 1. 准备翻译文件 2. 翻译字符串 3.设置应用程序语言 cmake 构建方式 示例代码 总结 1. 使用 file(GLOB ...) 2. 引入其他资源文件 再次生成翻译文件 5. 手动更新和生成.qm文件 其他资源 前言 在当今全球化的软件开发环境中,应用程…...
设计模式在Java项目中的实际应用
设计模式在Java项目中的实际应用 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 引言 设计模式是软件开发中重要的思想工具,它提供了解决特定问题…...
js制作随机四位数验证码图片
<div class"lable lable2"><div class"l"><span>*</span>验证码</div><div class"r"><input type"number" name"vercode" placeholder"请输入验证码"></div>&l…...
[开源软件] 支持链接汇总
“Common rules: 1- If the repo is on github, the support/bug link is also on the github with issues”" label; 2- Could ask questions by email list;" 3rd party software support link Note gcc https://gcc.gnu.org openssh https://bugzilla.mindrot.o…...
从零开始搭建spring boot多模块项目
一、搭建父级模块 1、打开idea,选择file–new–project 2、选择Spring Initializr,选择相关java版本,点击“Next” 3、填写父级模块信息 选择/填写group、artifact、type、language、packaging(后面需要修改)、java version(后面需要修改成和第2步中版本一致)。点击“…...
Iot解决方案开发的体系结构模式和技术
前言 Foreword 计算机技术起源于20世纪40年代,最初专注于数学问题的基本原理;到了60年代和70年代,它以符号系统为中心,该领域首先开始面临复杂性问题;到80年代,随着个人计算的兴起和人机交互的问题&#x…...
02.C1W1.Sentiment Analysis with Logistic Regression
目录 Supervised ML and Sentiment AnalysisSupervised ML (training)Sentiment analysis Vocabulary and Feature ExtractionVocabularyFeature extractionSparse representations and some of their issues Negative and Positive FrequenciesFeature extraction with freque…...
Stable Diffusion秋叶AnimateDiff与TemporalKit插件冲突解决
文章目录 Stable Diffusion秋叶AnimateDiff与TemporalKit插件冲突解决描述错误描述:找不到模块imageio.v3解决:参考地址 其他文章推荐:专栏 : 人工智能基础知识点专栏:大语言模型LLM Stable Diffusion秋叶AnimateDiff与…...
PCL 渐进形态过滤器实现地面分割
点云地面分割 一、代码实现二、结果示例🙋 概述 渐进形态过滤器:采用先腐蚀后膨胀的运算过程,可以有效滤除场景中的建筑物、植被、车辆、行人以及交通附属设施,保留道路路面及路缘石点云。 一、代码实现 #include <iostream> #include <pcl/io/pcd_io.h> #in…...
第十四届蓝桥杯省赛C++B组E题【接龙数列】题解(AC)
需求分析 题目要求最少删掉多少个数后,使得数列变为接龙数列。 相当于题目要求求出数组中的最长接龙子序列。 题目分析 对于一个数能不能放到接龙数列中,只关系到这个数的第一位和最后一位,所以我们可以先对数组进行预处理,将…...
Ubuntu 20.04.4 LTS 离线安装docker 与docker-compose
Ubuntu 20.04.4 LTS 离线安装docker 与docker-compose 要在Ubuntu 20.04.4 LTS上离线安装Docker和Docker Compose,你需要首先从有网络的环境下载Docker和Docker Compose的安装包,然后将它们传输到离线的服务器上进行安装。 在有网络的环境中:…...
vue3+ts 写echarts 中国地图
需要引入二次封装的echarts和在ts文件写的option <template><div class"contentPage"><myEcharts :options"chartOptions" class"myEcharts" id"myEchartsMapId" ref"mapEcharts" /></di…...
【设计模式】【行为型模式】【责任链模式】
系列文章目录 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录…...
超越所有SOTA达11%!媲美全监督方法 | UC伯克利开源UnSAM
文章链接:https://arxiv.org/pdf/2406.20081 github链接:https://github.com/frank-xwang/UnSAM SAM 代表了计算机视觉领域,特别是图像分割领域的重大进步。对于需要详细分析和理解复杂视觉场景(如自动驾驶、医学成像和环境监控)的应用特别有…...
享元模式(设计模式)
享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享细粒度对象来减少内存使用,从而提高性能。在享元模式中,多个对象可以共享相同的状态以减少内存消耗,特别适合用于大量相似对象的场景。 享元模…...
【机器学习】大模型训练的深入探讨——Fine-tuning技术阐述与Dify平台介绍
目录 引言 Fine-tuning技术的原理阐 预训练模型 迁移学习 模型初始化 模型微调 超参数调整 任务设计 数学模型公式 Dify平台介绍 Dify部署 创建AI 接入大模型api 选择知识库 个人主页链接:东洛的克莱斯韦克-CSDN博客 引言 Fine-tuning技术允许用户根…...
【Linux从入门到放弃】探究进程如何退出以进程等待的前因后果
🧑💻作者: 情话0.0 📝专栏:《Linux从入门到放弃》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢! 进…...
QT5 static_cast实现显示类型转换
QT5 static_cast实现显示类型转换,解决信号重载情况...
【ES】--Elasticsearch的翻页详解
目录 一、前言二、from+size浅分页1、from+size导致深度分页问题三、scroll深分页1、scroll原理2、scroll可以返回总计数量四、search_after深分页1、search_after避免深度分页问题一、前言 ES的分页常见的主要有三种方式:from+size浅分页、scroll深分页、search_after分页。…...
3.js - 纹理的重复、偏移、修改中心点、旋转
你瞅啥 上字母 // ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js // 导入twee…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
