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()的翻译标记,并确认lupdatelrelease工具的路径和执行是否正确。如果所有步骤正确完成,生成的.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博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BFS:队列+树的宽搜

一、二叉树的层序遍历 . - 力扣&#xff08;LeetCode&#xff09; 该题的层序遍历和以往不同的是需要一层一层去遍历&#xff0c;每一次while循环都要知道在队列中节点的个数&#xff0c;然后用一个for循环将该层节点走完了再走下一层 class Solution { public:vector<vec…

AUTOSAR以太网之IPv4

系列文章目录 返回总目录 文章目录 系列文章目录一、IPv4报文格式二、主要函数1.IPv4_Init()2.IPv4_Receive()3.IPv4_Transmit() 一、IPv4报文格式 二、主要函数 1.IPv4_Init() 这个函数除了对模块配置进行初始化&#xff0c;如果有分包和组包使能&#xff0c;则会对一些相关…

桌面提醒工具哪个好?简单好用的便签提醒app推荐

在日常的生活和工作中&#xff0c;我们经常会遇到各种各样的事情&#xff0c;有时候可能会遗忘一些重要的事情。这个时候&#xff0c;一个简单好用的便签提醒工具就显得尤为重要了。那么&#xff0c;哪款桌面提醒工具比较好用呢&#xff1f;下面&#xff0c;就为大家推荐一款我…

ONNX模型利用CUDA加速如何正确配置好环境?

目前onnx可选的执行引擎非常多&#xff0c;覆盖了从cpu、gpu到npu&#xff0c;从Intel平台到AMD平台等。如下是onnxruntime所有的执行引擎。 [TensorrtExecutionProvider, CUDAExecutionProvider, MIGraphXExecutionProvider, ROCMExecutionProvider, OpenVINOExecutionProvide…

基于公有云部署wordpress

云平台选择 腾讯云 阿里云 华为云 项目部署 一、架构讲解 1.1、定义与组成 LNMP是Linux、Nginx、MySQL&#xff08;或MariaDB&#xff09;和PHP&#xff08;或Perl、Python&#xff09;的首字母缩写&#xff0c;代表在Linux系统下使用Nginx作为Web服务器&#xff0c;MySQL作为…

Mongodb安装与配置

Mongodb的下载 这里下载的是MongoDB 7.0.11版本的 首先进入官网&#xff1a;https://www.mongodb.com/ 点击完上面两步后&#xff0c;加载来到该页面&#xff0c;选择自己的版本、系统&#xff0c;是压缩包(zip)还是安装包(msi)。 下载好之后能&#xff0c;来到安装包哪里&a…

互联网直播/点播技术与平台创新应用:视频推拉流EasyDSS案例分析

随着互联网技术的快速发展&#xff0c;直播/点播平台已成为信息传播和娱乐的重要载体。特别是在电视购物领域&#xff0c;互联网直播/点播平台与技术的应用&#xff0c;不仅为用户带来了全新的购物体验&#xff0c;也为商家提供了更广阔的营销渠道。传统媒体再一次切实感受到了…

wavesummit2024发布飞桨3.0版本

今天网上看了wavesummit2024深度学习开发者大会,本来没有啥期待&#xff0c;结果发现飞桨竟然发布3.0版本了&#xff01; 以下是飞桨框架 3.x 的新特性&#xff1a; 动静统一自动并行&#xff1a; 为了降低大模型的编程难度&#xff0c;飞桨还优化了动静统一的半自动并行编程范…

全国青少年信息素养大赛Python省赛真题

全国青少年信息素养大赛Python省赛真题 第一题 时间限制 : 1000ms 内存限制 : 256MB 【题目描述】 输入一个整数&#xff0c;输出这个整数加 8 的结果。 【输入描述】 输入一行一个正整数 【输出描述】 输出求和的结果。 样例 1 【输入】 5 【输出】 13 第二…

陪诊小程序开发:寻找陪诊师更加快速,全程陪护!

陪诊行业是一个新兴行业&#xff0c;在当下市场中具有较大的发展前景。对于无法陪家人看病或者对医院不熟悉的人来说&#xff0c;陪诊师成为了刚需&#xff01;目前随着社会的发展&#xff0c;人们的生活节奏不断加快&#xff0c;陪诊市场的需求量也在不断增加&#xff0c;发展…

荣耀终端发布首个端侧AI反诈检测技术,助力用户防范网络诈骗

在今日盛大开幕的2024年上海世界移动通信大会上&#xff0c;荣耀终端以卓越的创新实力引领行业潮流&#xff0c;率先发布了手机行业中首个端侧AI反诈检测技术。该技术旨在为用户提供更加安全、可靠的网络通信体验&#xff0c;助力防范日益猖獗的网络诈骗行为。 AI-321 | 专注全…

技巧类题目

目录 技巧类题目 136 只出现一次的数字 191 位1的个数 231. 2 的幂 169 多数元素 75 颜色分类 &#xff08;双指针&#xff09; 287. 寻找重复数 136 只出现一次的数字 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均…

【高考志愿】软件工程

目录 一、专业概述 二、就业前景 三、选择因素 3.1 学校实力 3.2 地理位置 3.3 分数线 四、学习建议 4.1 打好基础 4.2 培养动手能力 4.3 拓宽知识面 4.4 提升综合能力 五、软件工程专业学科排名 高考志愿选择软件工程专业是一个既具有挑战又充满机遇的决定。 一、…

【Redis四】主从复制、哨兵以及Cluster集群

目录 一.主从复制、哨兵、集群的区别 二.Redis主从复制 1.作用 2.原理 3.流程 三.搭建Redis 主从复制 1.源码编译安装以及配置文件修改 1.1.修改 Redis 配置文件&#xff08;Slave节点操作&#xff09; 2.验证主从复制 2.1.在Master节点上看日志 2.2.在Master节点上…

Raylib学习-鼠标检测与GPU缓冲区使用

鼠标左键点击运行绘制 #include <raylib.h>int main() {const int screenWidth 800;const int screenHeight 450;InitWindow(screenWidth, screenHeight, "test"); // 设置帧率SetTargetFPS(150); // 设置一个画布&#xff0c;可以使用GPU进行绘制RenderText…

虚拟化技术(二)

目录 三、存储虚拟化&#xff08;一&#xff09;存储虚拟化的一般模型&#xff08;二&#xff09;存储虚拟化的实现方式&#xff08;三&#xff09;案例分析 四、网络虚拟化&#xff08;一&#xff09;核心层网络虚拟化&#xff08;二&#xff09;接入层网络虚拟化&#xff08;…

【笔记】echarts图表的缩放和鼠标滚动冲突的处理解决方案

解决方案不是很好&#xff0c;来源于github的issue&#xff0c;官方提供了&#xff0c;组合键触发缩放的功能。 https://github.com/apache/echarts/issues/5769 https://echarts.apache.org/zh/option.html#dataZoom-inside.zoomOnMouseWheel dataZoom-inside.zoomOnMouseWhe…

Docker、Containerd添加代理

Docker、Containerd添加代理 博文的由来 国内网络环境下使用过docker的小伙伴&#xff0c;多数都会碰到一个一问题&#xff0c;由于连不上国外的dockerhub,导致无法pull需要的镜像&#xff0c;解决方案基本就四种 将镜像仓库地址切换到国内的镜像仓库使用别人打好的镜像包&am…

Android 12.0 通知发送过程源码分析-Framework

以下NotificationManagerService简称 NMS 1. 通知的发送: NotificationManager.notify(int id, Notification notification) 开始. 源码路径: /frameworks/base/core/java/android/app/NotificationManager.java/***发布通知以显示在状态栏中。 如果通知带有* 相同的 ID 已被…

debian打包小结

背景 业务需要&#xff0c;打一个openstack组件的deb包 openstack组件有setup.py可直接支持打rpm包&#xff0c;但不支持deb包&#xff0c;所以手动打deb包 用了dh_make准备打包文件&#xff0c;然后用debuild或dpkg-buildpackages打deb包 步骤 方法有很多&#xff0c;我用…