QT国际化
引入
在代码里面写中文就很low,运行时多语言切换是客户端程序都应该具备的。
qt国际化其实就是qt中字符串的字符集编码的设置。当然这个设置不是简单的选择一下什么语言就好,这个需要编程人员来处理的。
通常对于非拉丁字符(主要指latin1字符集)的字符串,就需要使用到unicode字符集,而通常使用UTF-8编码。如果只是本地使用一下,直接使用""包含文件就可以了。但是有时候设计到网络传输等情况,就要考虑这些了。
QT提供了QTextCodec类来进行文本字符集的转换操作。
本文的重点不在于此。深入学习可以看
QTextCodec && 字符编码
Qt 编码问题QTextCodec
本文的重点在于QT界面显示的中文化。
1、控制需要翻译的文本
在编写QT程序的时候,对于要翻译的文本,应当使用tr()包含起来。
我们先来看看tr函数的原型,注意,这是一个静态函数。
QString QObject::tr(const char * sourceText, const char * disambiguation = 0, int n = -1)
因为Qt中的类都继承自QObject类,所以这里直接使用了tr,如果不是在继承自QT的类中使用,应该用Object::tr(…)来调用。
这还不是很准确,在宏定义Q_OBJECT展开后,会创建一个QMetaObject对象,即static const QMetaObject staticMetaObject;这个可以看看源码
对于Q_OBJECT的解析可以看Qt信号与槽机制的基石-MOC详解
#define Q_OBJECT \public: \Q_OBJECT_CHECK \static const QMetaObject staticMetaObject;\Q_OBJECT_GETSTATICMETAOBJECT \virtual const QMetaObject *metaObject() const; \virtual void *qt_metacast(const char *); \QT_TR_FUNCTIONS \virtual int qt_metacall(QMetaObject::Call,int, void **); \private:
展开一个宏定义QT_TR_FUNCTIONS,而这里面定义了一个内联的tr函数。可以看出这里实际是使用了一个静态对象staticMetaObject的成员函数tr。
# define QT_TR_FUNCTIONS \static inline QString tr(const char *s, const char *c = 0) \{ return staticMetaObject.tr(s, c); } \static inline QString trUtf8(const char *s,const char *c = 0) \{ return staticMetaObject.trUtf8(s, c); } \static inline QString tr(const char *s,const char *c, int n) \{ return staticMetaObject.tr(s, c, n); } \static inline QString trUtf8(const char *s,const char *c, int n) \{ return staticMetaObject.trUtf8(s, c, n); }
例如对于一个QLabel控件,将其显示的文本使用tr括起来。tr是经过多级函数调用才实现了翻译操作,是有代价的,所以不该用的时候最好不要用。
QLable *label = new QLable(tr("hello"),this);
这次还是以一个hello world为例。
先看hello.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();
public slots:void btn_click();
};#endif // WIDGET_H
再看hello.cpp
#include "widget.h"
#include <QPushButton>
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent)
{//创建一个PushButtonQPushButton * btn = new QPushButton(tr("click me"),this);//连接信号和槽connect(btn,SIGNAL(clicked()),this,SLOT(btn_click()));
}Widget::~Widget()
{
}void Widget::btn_click()
{QMessageBox::information(NULL, tr("click button"),tr("hello world"), QMessageBox::Yes);
}
2、lupdate更新翻译
在上面,源文件中的相关字符串已经使用tr函数包装起来了。现在要做的就是更新这些要翻译的字符串到ts文件。
lupdate就是用于扫描pro文件中指定的代码或UI文件中被tr包装起来的文本的工具
lupdate的使用
lupdate的使用可以使用lupdate --help来查看。
粗略的说一下这个工具的用法:
使用方法:
lupdate [选项] [项目文件]…
lupdate [选项] [源文件 | 路径 | @ lst 文件]…-ts ts 文件 | @ lst 文件
(lst文件是一个文本文件,保存一些文件名称,一行一个)
常用选项 | 说明 |
---|---|
-ts … | 指定输出文件。 |
-codecfortr | 指定为 tr() 调用假设的编解码器。只有与-ts 有效。 |
-extensions [,]… | 扩展支持的文件后缀。扩展名列表必须用逗号分隔。默认值:‘java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml’。 |
-no-recursive | 指定不递归扫描的目录 |
-recursive | 递归扫描指定目录 |
-I or -I | 附加的包含文件目录 |
-no-ui-lines | 对ui文件的扫描不保留行号 |
-pro | .Pro 文件的名称。对于具有.pro 文件语法,但不同的文件后缀的文件非常有用。 |
-source-language [_] | 指定新文件的源字符串的语言。默认值Posix 标准。 |
-target-language [_] | 指定新文件翻译的语言。如果未指定,则猜测系统语言。 |
@lst-file | 从 lst 文件读取附加文件的名称 (每行一个)。 |
生成ts文件
1. 在命令行中指定方式生成
这里只生成一个翻译文件zh_hans.ts,其实可以跟多个文件名来生成多个用于翻译的ts文件。这个方式会忽略掉pro文件中指定要生成的翻译文件。
o@o-pc:~/hello$ lupdate hello.pro -ts zh_hans.ts
Updating 'zh_hans.ts'...Found 3 source text(s) (3 new and 0 already existing)
2. 在pro文件中指定
这里我们先修改一个hello.pro文件。
这是原本的hello.pro文件:
QT += core gui
TARGET = hello
TEMPLATE = app
SOURCES += main.cpp\hello.cpp
HEADERS += hello.h
LIBS += -lxcb
现在我们添加一句
TRANSLATIONS = zh_hans.ts
添加之后使用lupdate来生成zh_hans.ts文件
o@o-pc:~/hello$ lupdate hello.pro
3. linguits翻译文本
生成了ts文件后就要进行翻译了。ts文件实际上是类似于xml文件的,我们可以直接打开它来翻译。
- 直接翻译
打开ts文件,我们只需要在和之间填写我们翻译后的文件即可。
例如我们将"click me"翻译为点击我。则修改为:
<message><location filename="widget.cpp" line="9"/><source>click me</source><translation type="unfinished">点击我</translation>
</message>
如果你认为翻译合格了,没有问题了,可以将translation type=“unfinished”>中的type="unfinished"删除。
- 使用linguits工具翻译
1、点击菜单栏 文件 --> 打开 弹出文件选择对话框后选择生成的ts文件
2、设置源语言和目标语言,然而并没什么用
1、选择要翻译的短语
2、填写翻译的文本
3、翻译完成后记得保存
4. lrelease发布翻译
所谓发布翻译,就是使用lrelease工具将ts文件转换输出不包含多余信息的qm文件(qm文件是二进制文件,非文本文件)。
我们先来看看翻译后的ts文件。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context><name>Widget</name><message><location filename="widget.cpp" line="9"/><source>click me</source><translation>点击我^_^</translation></message><message><location filename="widget.cpp" line="20"/><source>click button</source><translation>单击按钮</translation></message><message><location filename="widget.cpp" line="21"/><source>hello world</source><translation>你好 世界</translation></message>
</context>
</TS>
使用lrelease生成qm文件
o@o-pc:~/hello$ lrelease zh_hans.ts -qm zh_hans.qm
lrelease使用简要说明
使用方法:
lrelease [选项] 项目文件
lrelease [选项] ts 文件 [-qm qm 文件]
选项 | 说明 |
---|---|
-idbased | 使用 Id 而不是源字符串作为消息的键 |
-compress | QM 文件压缩 |
-nounfinished | 不使用未完成的翻译 |
-removeidentical | 如果源文本与翻译后的文本相同,不使用这个 |
-markuntranslated | 如果消息有没有真正的翻译,使用源文本和 |
5. 在程序中使用翻译文件
在QT程序中要使用翻译文件,需要使用到类QTranslation。现在来修改main.cpp.
#include "widget.h"
#include <QApplication>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator tsor; //创建翻译器tsor.load("zh_hans.qm"); //加载语言包a.installTranslator(&tsor); //安装翻译器Widget w;w.show();return a.exec();
}
参考
- QT国际化(lupdate/linguits/lrelease)
相关文章:
QT国际化
引入 在代码里面写中文就很low,运行时多语言切换是客户端程序都应该具备的。 qt国际化其实就是qt中字符串的字符集编码的设置。当然这个设置不是简单的选择一下什么语言就好,这个需要编程人员来处理的。 通常对于非拉丁字符(主要指latin1字符…...

微信小程序button按钮去除边框去除背景色
button边框 去除button边框 在button上添加plain“true”在css中添加button.avatar-wrapper {background: none}用于去除button背景色在css中添加button.avatar-wrapper[plain]{ border:0 }用于去除button边框...

Neo4j深度学习
Neo4j的简介 Neo4j是用Java实现的开源NoSQL图数据库。从2003年开始开发,2007年正式发布第一版,其源码托管于GitHtb。Neo4j作为图数据库中的代表产品,已经在众多的行业项目中进行了应用,如:网络管理、软件分析、组织和…...
【数据结构C/C++】链式存储与顺序存储结构栈
文章目录 链式存储结构顺序存储结构 下面这篇文章是我大二时候写的比较详细的实现过程,再这篇文章我也会再一次比较简单的再次简述一下链式与顺序存储结构的实现方式。 链式存储结构与顺序存储结构详解 这里我就不使用C再一次实现这两个栈了,有兴趣的也可…...
【数据库系统概论】数据定义之基本表的定义/创建、修改和删除
前言 🚩定义/创建基本表语法示例 修改基本表语法示例 删除基本表语法示例 感谢 💖 前言 🚩 SQL支持数据库系统的三级模式结构,其模式、外模式和内模式中的基本对象有表、视图和索引,因此,SQL的数据定义功能…...

面试算法22:链表中环的入口节点(1)
题目 如果一个链表中包含环,那么应该如何找出环的入口节点?从链表的头节点开始顺着next指针方向进入环的第1个节点为环的入口节点。 例如,在如图4.3所示的链表中,环的入口节点是节点3。 分析 第1步:确认是否包含环…...

蓝桥杯---第二讲---二分与前缀和
文章目录 前言Ⅰ. 数的范围0x00 算法思路0x00 代码书写 Ⅱ. 数的三次方根0x00 算法思路0x01代码书写 Ⅲ. 前缀和0x00 算法思路0x01 代码书写 Ⅳ. 子矩阵的和0x00 算法思路0x01 代码书写 Ⅴ. 机器人跳跃问题0x00 算法思路0x01 代码书写 Ⅵ. 四平方和0x00 算法思路0x01 代码书写 …...

d3dx9_39.dll如何修复?最新修复d3dx9_39.dll方法分享
大家好!今天我要和大家分享的主题是“d3dx9_39.dll丢失的修复方法”。我们都知道,在使用电脑的过程中,经常会遇到各种问题,而其中最常见的就是文件丢失。d3dx9_39.dll就是其中一个常见的丢失文件。那么,如何修复这个丢…...

阿里云轻量应用服务器月流量限制说明(部分套餐不限流量)
阿里云轻量应用服务器部分套餐限制月流量,轻量应用服务器按照套餐售卖,有的套餐限制月流量,有的不限制流量。像阿里云轻量2核2G3M带宽轻量服务器一年108元和轻量2核4G4M带宽一年297.98元12个月,这两款是不限制月流量的。阿里云百科…...

项目设计:YOLOv5目标检测+机构光相机(intel d455和d435i)测距
1.介绍 1.1 Intel D455 Intel D455 是一款基于结构光(Structured Light)技术的深度相机。 与ToF相机不同,结构光相机使用另一种方法来获取物体的深度信息。它通过投射可视光谱中的红外结构光图案,然后从被拍摄物体表面反射回来…...

WPF中DataContext的绑定技巧
先看效果: 上面的绑定值都是我们自定义的属性,有了以上的提示,那么我们可以轻松绑定字段,再也不用担心错误了。附带源码。 目录 1.建立mvvm项目 2.cs后台使用DataContext绑定 3.xaml前台使用DataContext绑定 4.xaml前台使用Da…...
【Spring MVC研究】MVC原理:DispatcherServlet的初始化,初始化好等于MVC准备好
文章目录 1. EnableWebMVC 开启 MVC 功能2. 初始化自定义的 MVC 组件2.1. 初始化过程2.2. 如何分析复杂的 Spring 组件注册 3. 容器启动后会初始化 DispatcherServlet4. DispatcherServlet 初始化过程总结5. 资料参考 把DispatcherServlet 准备好意味着服务器已经可以处理请求了…...

Kafka的分布式架构与高可用性
导语 一开始我们就说过Kafka是一款开源的高吞吐、分布式的消息队列系统,那么今天我们就来说下它的分布式架构和高可用性以及双/多中心部署。 Kafka 体系架构简介 以下是 Kafka 的软件架构,整个 Kafka 体系结构由 Producer、Consumer、Broker、ZooKeepe…...

Spring Cloud学习笔记【分布式请求链路跟踪-Sleuth】
文章目录 Spring Cloud Sleuth概述概述主要功能:Sleuth中的术语和相关概念官网 zipkin配置下载运行zipkin下载zipkin运行 demo配置服务提供者 lf-userpom.xmlapplication.ymlUserController 服务调用者 lf-authpom.xmlapplication.ymlAuthController 测试 Spring Cl…...
Java开发中的操作日志详解(InsCode AI 创作助手)
Java开发中的操作日志详解 一、操作日志的作用 故障排除和调试: 操作日志可以记录应用程序的各种活动,包括错误、异常、警告和信息性消息。这有助于开发人员快速定位和解决问题。性能分析: 通过记录关键操作和性能指标,操作日志…...
FutureTask和CompletableFuture的模拟使用
模拟了查询耗时操作,并使用FutureTask和CompletableFuture分别获取计算结果,统计执行时长 package org.alllearn.futurtask;import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; imp…...

Redis作为缓存,mysql的数据如何与redis进行同步?
Redis作为缓存,mysql的数据如何与redis进行同步? 一定要设置前提,先介绍业务背景 延时双删 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致 读操作:缓存命中,直接返回;缓存未…...

申请免费 SSL 证书为您的小程序加密通信
在今天的网络环境中,数据安全和隐私保护变得尤为重要。无论是网站还是应用程序,为其提供安全的通信渠道都是至关重要的。对于小程序开发者来说,使用 SSL(Secure Sockets Layer)证书可以有效地保障用户数据的安全&#…...

Go 并发编程
并发编程 1.1 并发与并⾏ 并⾏与并发是两个不同的概念,普通解释: 并发:交替做不同事情的能⼒并⾏:同时做不同事情的能⼒ 如果站在程序员的⻆度去解释是这样的: 并发:不同的代码块交替执⾏并⾏…...

鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结
本文介绍两种方法 1、经纬度矫正法 2、棋盘格矫正法 一、经纬度矫正法 1、算法说明 经纬度矫正法, 可以把鱼眼图想象成半个地球, 然后将地球展开成地图,经纬度矫正法主要是利用几何原理, 对图像进行展开矫正。 经过P点的入射光线…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...