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点的入射光线…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...