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…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
