Qt5开发及实例V2.0-第十四章-Qt多国语言国际化

news2024/10/3 22:14:50

Qt5开发及实例V2.0-第十四章-Qt多国语言国际化

  • 第14章 Qt 5多国语言国际化
    • 14.1 基本概念
      • 14.1.1 国际化支持的实现
      • 14.1.2 翻译工作:“*.qm”文件的生成
    • 14.2 【实例】
      • 14.2.1 简单测试
      • 14.2.2 选择语言翻译文字
  • 本章相关例程源码下载
    • 1.Qt5开发及实例_CH1401.rar 下载
    • 2.Qt5开发及实例_CH1402.rar 下载

第14章 Qt 5多国语言国际化

14.1 基本概念

14.1.1 国际化支持的实现

(1)使用QString对象表示所有用户可见的文本。由于QString内部使用Unicode编码实现,所以它可以用于表示所有需要向用户呈现的文本。当然,对于仅程序员可见的文本并不需要都变为QString对象,可利用Qt提供的QCString或原始的“char *”。
(2)使用tr()函数获取所有需要翻译的文本。在Qt的翻译机制下,QObject::tr()函数可以帮程序员取得翻译之后的文本。对于从QObject继承而来的类,QObject::tr()函数最终由QMetaObject::tr()实现。在某些时候,如果无法使用QObject::tr()函数,则还可以直接调用QCoreApplication::translate()取得翻译之后的字符串。

(3)使用QString::arg()组织动态文本。有些时候,一段文本需要由一些静态文本和动态变量组合起来,如常见的情况“printf(“The value of i is: %d”, i)”。对于这种动态文本的翻译,由于语言习惯的问题,如果简单地采用这种连接字符串的方法,则可能会带来一些问题,如下面的字符串用于表示任务的完成情况:
QString m = tr("Mission status: " )+ x + tr("of ") + y +tr(“are completed”);
(4)利用QTranslator::load()和QCoreApplication::installTranslator()读取对应的翻译之后的资源文件。翻译工作者将提供包含有翻译之后的字符串的资源文件“*.qm”,程序员还需要做的是定义QTranslator对象,并使用load()函数读取相应的“.qm”文件,利用QCoreApplication::installTranslator()函数安装QTranslator对象。

14.1.2 翻译工作:“*.qm”文件的生成

(1)利用lupdate工具从源代码中扫描并提取需要翻译的字符串,生成“.ts”文件。类似编译时用到的qmake,运行lupdate时也需要指定一个“.pro”的文件,这个“.pro”文件可以单独创建,也可以利用编译时用到的“.pro”文件,只需定义好变量TRANSLATIONS即可,具体用法可以参见本书后面的小例子。
(2)利用linguist工具来协助完成翻译工作,即打开前面用lupdate生成的“.ts”文件,对其中的字符串逐条进行翻译并保存。由于“.ts”文件采用了XML格式,所以也可以使用其他编辑器来打开“.ts”文件并翻译。
(3)利用lrelease工具处理翻译好的“.ts”文件,生成格式更为紧凑的“.qm”文件。这便是翻译工作者最终需要提供的资源文件,它所占的空间比“.ts”文件小,但基本不具有可读性,只有QTranslator能够正确地识别它。

14.2 【实例】

14.2.1 简单测试

【例】(简单)(CH1401)多国语言国际化。
操作步骤如下。
(1)新建一个GUI工程“TestHello.pro”,在UI界面上添加两个按钮,并分别将文本修改为hello、china,如图14.1所示。
在这里插入图片描述

(2)修改“TestHello.pro”文件,添加如下代码:
TRANSLATIONS = TestHello.ts
(3)编译。记住,一定要先编译,假如没有编译就进行下面的步骤,生成的“.ts”文件只是一个仅有标题栏的框架。
(4)编译完成后,选择“开始”→“所有程序”→“Qt 5.8.0”→“5.8”→“MinGW 5.3.0 (32-bit)”→“Qt 5.8 for Desktop (MinGW 5.3.0 32 bit)”菜单项,打开命令行窗口,进入“TestHello.pro”工程目录,执行命令:
lupdate TestHello.pro
在工程下生成一个“.ts”文件,假如没有编译,将提示“Found 1 source text”。若已经编译,就将提示“Found 3 source text(s)”,如图14.2所示。
在这里插入图片描述

(5)选择“开始”→“所有程序”→“Qt 5.8.0”→“5.8”→“MinGW 5.3.0 (32-bit)”→“Linguist”菜单项,运行Qt自带工具Linguist(Qt 语言家),其主界面如图14.3。
在这里插入图片描述
在主界面上选择“文件”→“打开”命令,选择“TestHello.ts”文件,单击“打开”按钮,根据需要设置源语言和目标语言,此处为默认状态:源语言为任意国家语言,目标语言为China的Chinese,如图14.4所示。
在这里插入图片描述
(6)在第二栏中选择要翻译的字符串,在下面两行中输入对应的翻译文字,单击上面的 按钮,如图14.5所示。
在这里插入图片描述

(7)选择“文件”→“发布”菜单项,或者在命令行中输入“lrelease TestHello.pro”,生成“TestHello.qm”文件,如图14.6所示。
在这里插入图片描述

(8)修改源代码,其中,加黑语句为需要添加的部分。
具体代码如下:

#include<QTranslator>
int main(int argc, char *argv[]) 
{
	QApplication a(argc, argv);
	QTranslator *translator = new QTranslator;
	translator->load("D:/Qt/CH14/CH1401/TestHello/TestHello.qm");
	a.installTranslator(translator);
	MainWindow w;
	w.show();
	return a.exec();
}

(9)运行程序,效果如图14.7所示。
在这里插入图片描述

14.2.2 选择语言翻译文字

【例】(简单)(CH1402)用一个下拉菜单来选择语言,并且下面有一个需要翻译文字的标签。
实现步骤如下。
(1)在头文件“LangSwitch.h”中定义类LangSwitch,创建用户界面。

#include <QWidget>
#include <QComboBox>
#include <QLabel>
class LangSwitch : public QWidget
{
     Q_OBJECT
public:
     LangSwitch(QWidget *parent = 0);
     ~LangSwitch();
private slots:
     void changeLang(int index);		//(a)
private:
     void createScreen();			//(b)
     void changeTr(const QString& langCode);
     void refreshLabel();
     QComboBox* combo;			//界面中可以看见的下拉菜单
     QLabel* label;			//界面中可以看见的标签
};

(2)源文件“LangSwitch.cpp”中的具体实现代码如下:

#include "langswitch.h"
#include <QVBoxLayout>
#include <QTranslator>
#include <QApplication>
LangSwitch::LangSwitch(QWidget *parent)
     : QWidget(parent)
{
     createScreen();
}
LangSwitch::~LangSwitch()
{
}

createScreen()函数用于创建基本的界面,其具体实现代码如下:

void LangSwitch::createScreen()
{
    combo = new QComboBox;
    combo->addItem("English", "en");			//(a)
    combo->addItem("Chinese", "zh");
    combo->addItem("Latin", "la");
    label = new QLabel;
    refreshLabel();										//设置标签的内容
    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(combo, 1);
    layout->addWidget(label, 5);
    setLayout(layout);
    connect(combo, SIGNAL(currentIndexChanged(int)),
          this, SLOT(changeLang(int)));			//(b)
}

refreshLabel()函数的具体实现如下:

void LangSwitch::refreshLabel()
{
      label->setText(tr("TXT_HELLO_WORLD", "Hello World"));	//(a)
}

changeLang()函数改变语言的具体代码如下:

void LangSwitch::changeLang(int index)
{
      QString langCode = combo->itemData(index).toString();	//(a)
      changeTr(langCode);		//读取相应的“.qm”文件
      refreshLabel();			//刷新标签上的文字
}

函数changeTr()读取对应的“.qm”文件,并调用installTranslator()方法安装QTranslator对象,其具体实现代码如下:

void LangSwitch::changeTr(const QString& langCode)
{
    static QTranslator* translator;				//(a)
    if(translator != NULL)
    {
       	qApp->removeTranslator(translator);
       	delete translator;
       	translator = NULL;
    }
    translator = new QTranslator;
    QString qmFilename = "lang_" + langCode;			//(b)
    if(translator->load(QString("D:/Qt/CH14/CH1402/LangSwitch/")+qmFilename))
    {
        	qApp->installTranslator(translator);
    }
}

(3)提取需要翻译的字符串并翻译,生成“.qm”文件(这个工作通常由专门的工作组负责),具体操作如下。
① 修改“langswitch.pro”文件,即在后面加上TRANSLATIONS的定义(加黑部分代码)。修改完的“langswitch.pro”文件的具体内容如下:

TARGET = LangSwitch
TEMPLATE = app
SOURCES += main.cpp\
       langswitch.cpp
HEADERS  += langswitch.h
TRANSLATIONS = lang_en.ts \
               lang_zh.ts \
               lang_la.ts

此时运行结果如图14.8所示。
在这里插入图片描述

② 利用lupdate工具提取需要翻译的字符串,运行命令及结果如图14.9所示。
在这里插入图片描述
(a)利用Linguist翻译这几个“.ts”文件。直接利用Qt的Linguist工具打开需要翻译的“.ts”文件,就可以进行字符串的翻译,这里三个版本的字符串分别译为“Hello World”(English)、“你好,世界”(Chinese)和“Orbis, te saluto”(Latin),翻译完成后保存退出,如图14.10所示。
在这里插入图片描述
(b)生成各个“.ts”文件相应的“.qm”文件。这个工作可以利用lrelease来完成,其用法与lupdate工具相同,只是改用命令“lrelease LangSwitch.pro”,命令的运行情况如图14.11所示。
在这里插入图片描述

上述所有准备工作完成后,便可运行程序,效果如图14.12所示。
在这里插入图片描述



本章相关例程源码下载

1.Qt5开发及实例_CH1401.rar 下载

Qt5开发及实例_CH1401.rar

2.Qt5开发及实例_CH1402.rar 下载

Qt5开发及实例_CH1402.rar

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

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

相关文章

基于Xml方式Bean的配置-命名空间种类

Spring的标签 Spring的xml标签大体上分为两类&#xff0c;一种是默认标签&#xff0c;一种是自定义标签 默认标签&#xff1a;就是不用额外导入其它命名空间约束的标签&#xff0c;例如<bean>标签 标签作用 <beans> 一般作为xml配置根标签&#xff0c;其他标签都是…

如何利用播放器节省20%点播成本

点播成本节省的点其实涉及诸多部分&#xff0c;例如&#xff1a;CDN、转码、存储等&#xff0c;而利用播放器降本却是很多客户比较陌生的部分。火山引擎基于内部支撑抖音集团相关业务的实践&#xff0c;播放器恰恰是成本优化中最重要和最为依赖的部分。 火山引擎的视频团队做了…

基于复旦微的FMQL45T900全国产化ARM开发开发套件(核心板+底板)

TES745D是我司自主研制的一款基于上海复旦微电子FMQL45T900的全国产化ARM核心板&#xff08;模块&#xff09;。该核心板将复旦微的FMQL45T900&#xff08;与XILINX的XC7Z045-2FFG900I兼容&#xff09;的最小系统集成在了一个87*117mm的核心板上&#xff0c;可以作为一个核心模…

JavaWeb开发-08-MySQL(三)

一.多表查询 -- 多表查询: 数据准备 -- 部门管理 create table tb_dept(id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null comment 创建时间,update_time datetime not null comm…

数据治理-重要图

语境关系图 车轮图 六边形图

LLMs之InternLM:InternLM-20B的简介、安装、使用方法之详细攻略

LLMs之InternLM&#xff1a;InternLM-20B的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年09月20日&#xff0c;由上海人工智能实验室等团队发布了InternLM-20B的大模型。它在OpenCompass提出的5个能力维度上(语言、知识、理解、推理、学科)全面领先于同规模开源模型&…

华为数通方向HCIP-DataCom H12-831题库(单选题:121-140)

第121题 在华为交换机上配置RADIUS服务器模板时,下列选项中哪些参数为可选的配置参数? A、认证服务器地址和端口 B、RADIUS自动探测用户 C、计费服务器地址和端口 D、Shared-key 答案: B 解析: 在华为交换机上配置 radius 服务器模板时,需要配置共享秘钥,认证服务器地址…

保研CS/软件工程/通信问题汇总

机器学习 1.TP、TN、FP、FN、F1 2.机器学习和深度学习的区别和联系 模型复杂性&#xff1a;深度学习是机器学习的一个子领域&#xff0c;其主要区别在于使用深层的神经网络模型。深度学习模型通常包含多个隐层&#xff0c;可以学习更加复杂的特征表示&#xff0c;因此在某些任…

datax同步数据翻倍,.hive-staging 导致的问题分析

一、背景 有同事反馈 Datax 从 Hive 表同步数据到 Mysql 数据翻倍了。通过查看 Datax 任务日志发现&#xff0c;翻倍的原因是多读取了 .hive-staging_xx 开头的文件。接下里就是有关 .hive-staging 的分析。 二、环境 Hive 版本 2.1.1 三、分析 3.1 .hive-staging_hive 产…

2023最新SSL证书在线申请系统源码 | 支持API接口

2023最新SSL证书在线申请系统源码 | 支持API接口 SSL证书保证网络安全的基本保障。向您介绍我们的在线生成SSL证书系统 支持在线生成SSL证书系统&#xff0c;用户登录可在线申请SSL&#xff0c;后台对接ssl证书API接口 测试运行环境&#xff1a;NginxPHP8.0MySQL5.7 源码下…

【计算机网络】图解路由器(二)

本系列包含&#xff1a; 图解路由器&#xff08;一&#xff09;图解路由器&#xff08;二&#xff09; 图解路由器&#xff08;二&#xff09; 21、什么是静态路由&#xff1f;22、什么是动态路由&#xff1f;23、动态路由有哪些类型&#xff1f;24、什么是 RIP &#xff1f;2…

【Spring中的设计模式】

文章目录 Spring中的设计模式1.控制反转(IoC)和依赖注入(DI)2.工厂设计模式3.单例设计模式实现方式Spring中的单例模式 4.代理设计模式代理模式在 AOP 中的应用Spring AOP 和 AspectJ AOP 有什么区别? 5.模板方法6.观察者模式Spring 事件驱动模型中的三种角色事件角色事件监听…

3、ARIMA序列预测Matlab代码、可视化(可做算法对比)

1、文件包中程序均收集、整理、汇总自网络。 2、文件包完整内容&#xff1a; 1&#xff09;【ARIMA-功能函数】仅包含一个ARIMA算法函数&#xff0c;需要调用到自己的程序中使用。 函数部分代码及预览图&#xff1a; function [result] ARIMA_algorithm(data, Periodicity,…

实现YOLOv5封装成函数以供其他程序进行调用

import detect detect.UAPI(source"data/images") 通过在YOLOv5中的detect.py的代码中&#xff0c;对检测函数进行封装&#xff0c;之后其他代码通过已经封装好的函数进行调用&#xff0c;从而实现简单便捷的YOLOv5代码调用。 代码的主要修改部分就是如何detect.py…

pytest之parametrize()实现数据驱动

第一个参数是字符串&#xff0c;多个参数中间用逗号隔开 第二个参数是list,多组数据用元组类型;传三个或更多参数也是这样传。list的每个元素都是一个元组&#xff0c;元组里的每个元素和按参数顺序一一对应 传一个参数 pytest.mark.parametrize(‘参数名’&#xff0c;list)…

《从菜鸟到大师之路 ElasticSearch 篇》

《从菜鸟到大师之路 ElasticSearch 篇》 &#xff08;一&#xff09;&#xff1a;ElasticSearch 基础概念、生态和应用场景 为什么需要学习 ElasticSearch 根据 DB Engine 的排名显示&#xff0c; ElasticSearch 是最受欢迎的 企业级搜索引擎 。下图红色勾选的是我们前面的系…

算法基础之二分查找

原题链接 一 、二分查找中的mid1和mid-1的问题 二分查找中的边界问题处理不好很容易导致死循环和计算错误的问题&#xff0c;以题目 数的范围为例。 题目大意 ​ 二分查找重复数第一次出现的位置和最后一次出现的位置。 数学含义 ​ 第一次位置即 找到 一个长度最大的 >X 区…

[代码解读] A ConvNet for the 2020s

代码地址&#xff1a;https://github.com/facebookresearch/ConvNeXt ConvNeXt/models/convnext.py整体的代码结构如下&#xff1a; 接下来我们一部分一部分来看。 1.Block类&#xff1a; class Block(nn.Module):r""" ConvNeXt Block. There are two equiva…

Redis集群架构搭建——主从、哨兵、集群

上一篇文章Ubuntu上通过源码方式安装Redis已经介绍了如何安装redis&#xff0c;在这篇文章中&#xff0c;将会教大家搭建Redis的几种高可用的架构&#xff1a;主从架构、哨兵集群、Cluster集群。 本篇文章使用的redis版本为6.2.13&#xff0c;不同版本的配置可能有略微的区别&a…

C++:list

目录 List的模拟实现 List节点类 List链表结构 List迭代器类 结构 T& operator*(); T& operator->(); Self& operator(); Self operator(int); Self& operator--(); Self& operator--(int); bool operator!(const Self& l); bool oper…