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…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

aurora与pcie的数据高速传输
设备:zynq7100; 开发环境:window; vivado版本:2021.1; 引言 之前在前面两章已经介绍了aurora读写DDR,xdma读写ddr实验。这次我们做一个大工程,pc通过pcie传输给fpga,fpga再通过aur…...