Qt翻译(本地化)坑总结

news2025/1/17 4:39:18

文章目录

  • 坑1:无法生成ts文件
  • 坑2:ts文件的中文乱码
  • 坑3:不能直接翻译全局变量、静态变量、符号常量字符串

官方文档 Internationalization with Qt
贴一个比较好的总结 Qt中,软件多语言国际化翻译的方法与步骤


坑1:无法生成ts文件

实测在VS2013+QT 5.9上,点击Create New Translation File无法生成ts文件
在这里插入图片描述
提示ExitCode 1
在这里插入图片描述
注:在VS2015+Qt5.12上就没有问题
因此只能通过qt cmd的方式生成,首先在VS中生成.pro文件,然后在.pro最后添加ts文件

TRANSLATIONS += xxxxx_zh.ts\
	xxxxx_en.ts

运行qt cmd,输入 lupdate pro文件路径
在这里插入图片描述
此处会警报,解决办法见 Qt cmd警告 WARNING: Project ERROR: Cannot run compiler ‘cl‘ 解决办法

WARNING: Project ERROR: Cannot run compiler 'cl'. Output:
===================
===================
Maybe you forgot to setup the environment?

生成.ts文件,把ts文件拖进VS就会自动用Linguist打开

Info: creating stash file C:\Qt\Qt5.9.7\5.9.7\msvc2013_64\.qmake.stash
Updating 'xxxxxx/xxxxx_zh.ts'...
    Found 16 source text(s) (16 new and 0 already existing)
Updating 'xxxxxx/xxxxx_en.ts'...
    Found 16 source text(s) (16 new and 0 already existing)

VS里的lrelease也不能用了,把上面cmd指令里的lupdate 改为lrelease 运行即可
在这里插入图片描述
生成.qm文件

Info: creating stash file C:\Qt\Qt5.9.7\5.9.7\msvc2013_64\.qmake.stash
Updating 'xxxxxx/xxxxx_zh.qm'...
    Generated 2 translation(s) (0 finished and 2 unfinished)
    Ignored 14 untranslated source text(s)
Updating 'xxxxxx/xxxxx_en.qm'...
    Generated 0 translation(s) (0 finished and 0 unfinished)
    Ignored 16 untranslated source text(s)

上面显示unfinished是因为在Linguist中没有确认,此时ts文件中会显示<translation type="unfinished">,确认后会取消unfinished标记
在这里插入图片描述

上面的过程可以简化为三个批处理文件:run_qt_cmd.bat打开qt cmd窗口,cmd_lupdate.bat生成.ts文件,cmd_lrelease.bat生成.qm文件,以下给出批处理文件:
(以QT5.9+MSVC2013 X64为例)
run_qt_cmd.bat

C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\Qt5.9.7\5.9.7\msvc2013_64\bin\qtenv2.bat

这一串命令可以通过cmd快捷方式获得
在这里插入图片描述
在这里插入图片描述

cmd_lupdate.bat

set path=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64;%path%
lupdate pro文件路径

cmd_lrelease.bat

set path=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64;%path%
lrelease  pro文件路径

使用方法:首先运行run_qt_cmd.bat打开cmd窗口,需要生成ts文件时将cmd_lupdate.bat拖进cmd;需要生成qm文件时将cmd_lrelease.bat拖进cmd


坑2:ts文件的中文乱码

用Linguist打开ts文件,里面的中文显示乱码。
在这里插入图片描述

ts文件本质就是一个xml,<?xml version="1.0" encoding="utf-8"?>,Qt Creator默认编码UTF8,VS则是GB2312,如果源代码里面存在中文的字面量字符串(Literal String),如tr("中文字符串"),lupdate会自动将中文字符串转为UTF8从而导致乱码
查看官方文档QObject::tr

[static] QString QObject::tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1)
Returns a translated version of sourceText, optionally based on a disambiguation string and value of n for strings containing plurals; otherwise returns QString::fromUtf8(sourceText) if no appropriate translated string is available.

QObject::tr会按照UTF8读取文本

所以,源代码中待翻译的文本(用tr包含的字符串),使用拉丁字母表示,可以是文本对应的英文的大概意思,甚至是中文拼音,只要方便翻译人员在Linguist中对照即可


坑3:不能直接翻译全局变量、静态变量、符号常量字符串

因为全局变量、静态变量初始化发生在QTranslator::installTranslator之前,Qt无法替换(翻译)这些变量。而通过QT_TR_NOOP宏可以标识出静态生存期变量,让Qt可以晚一些再翻译这些变量,称为delayed translation,见官方文档QT_TR_NOOP的说明:

QT_TR_NOOP(sourceText)
Marks the UTF-8 encoded string literal sourceText for delayed translation in the current context (class).
The macro tells lupdate to collect the string, and expands to sourceText itself.

官方的示例:

QString FriendlyConversation::greeting(int type)
{
    static const char *greeting_strings[] = {
        QT_TR_NOOP("Hello"),
        QT_TR_NOOP("Goodbye")
    };
    return tr(greeting_strings[type]);
}

注意它明确提到 in the current context (class),例子中的静态字符串位于FriendlyConversation类作用域中,显然FriendlyConversation要不是QObject对象,要不是经过声明了Q_DECLARE_TR_FUNCTIONS宏,翻译动作始终需要由
QCoreApplication::translate来完成。Q_DECLARE_TR_FUNCTIONS的宏定义如下:

#define Q_DECLARE_TR_FUNCTIONS(context) \
public: \
    static inline QString tr(const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) \
        { return QCoreApplication::translate(#context, sourceText, disambiguation, n); } \
    QT_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \
private:

对于常量字符串、符号常量字符串,它们甚至在编译时就被编译器替换好了,就更不可能经QCoreApplication::translate翻译了。像下面的做法都是徒劳:

#define DEFINE_MESSAGE_ QT_TR_NOOP("Failed to 1")
const char *kConstMessage = QT_TR_NOOP("Failed to 2");
static const char *kStaticConstMessage = QT_TR_NOOP("Failed to 3");
...
	QMessageBox::critical(nullptr, tr("Error"), tr(DEFINE_MESSAGE_);
	QMessageBox::critical(nullptr, tr("Error"), tr(kConstMessage);
	QMessageBox::critical(nullptr, tr("Error"), tr(kStaticConstMessage);
...

一种替代方案是通过一个类封装全局变量,并将类声明Q_DECLARE_TR_FUNCTIONS宏或者继承QObject

//GlobalMessageWarpper.h
class GlobalMessageWarpper
{
	Q_DECLARE_TR_FUNCTIONS(GlobalMessageWarpper)
public:
	static QString message() { return tr(kMessage); }
	static const char* kMessage;
};
//GlobalMessageWarpper.cpp
const char* GlobalMessageWarpper::kMessage = QT_TR_NOOP("Failed to ...");
//main.cpp
...
QMessageBox::critical(nullptr, tr("Error"), GlobalMessageWarpper::message());
...

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

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

相关文章

[Redis] Redis实战

✨✨个人主页:沫洺的主页 &#x1f4da;&#x1f4da;系列专栏: &#x1f4d6; JavaWeb专栏&#x1f4d6; JavaSE专栏 &#x1f4d6; Java基础专栏&#x1f4d6;vue3专栏 &#x1f4d6;MyBatis专栏&#x1f4d6;Spring专栏&#x1f4d6;SpringMVC专栏&#x1f4d6;SpringBoot专…

[附源码]java毕业设计实践教学管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Echarts:好玩的timeline

Echarts是一个开源的可视化图表库&#xff0c;支持丰富的图表&#xff0c;官网中还有大量示例可以选择使用、参考。 其中比较有趣的一个特性是可以把数据随时间变化而变化&#xff0c;其效果与一些视频中比较不同国家的国力随时间变化的排名变化的效果相似。 接下啦我们就实现…

linux下golang环境安装教程(学习笔记)

linux下golang环境安装教程&#xff08;学习笔记&#xff09; SSH远程登录linux服务器 安装 mercurial包 [rootlocalhost ~]# yum install mercurial 安装git包 [rootlocalhost ~]# yum install git 安装gcc【一般自带安装好了的】 [rootlocalhost ~]# yum install gcc …

黑*头条_第3章_文章详情前后端成形记

黑*头条_第3章_文章详情前后端成形记 文章目录黑*头条_第3章_文章详情前后端成形记文章详情前后端成形记1 分布式主键封装1.1 依赖导入1.2 配置文件1.3 枚举封装1.4 序列封装1.5 Client封装1.6 Config封装1.7 Sequences封装1.8 使用案例1.9 扩展自增表2 App文章详情2.1 功能需求…

Spring IOC源码:registerBeanPostProcessors 详解

前言 上篇文章介绍了后置处理器BeanFactoryPostProcessor的注册、实例化及执行操作&#xff0c;这节介绍一下另外一个后置处理器BeanPostProcessor。前者是针对BeanFactory工厂对象进行增上改查操作&#xff0c;在bean实例化之前&#xff0c;我们可以修改其定义。后者是对实例…

电脑重装系统蓝屏是什么原因

​电脑蓝屏是由于系统故障、致命的系统错误或系统崩溃而导致的现象&#xff0c;要想修复电脑蓝屏&#xff0c;关键是找出原因所在。为此&#xff0c;下面小编就给大家整理电脑蓝屏是什么原因。 原因1、虚拟内存不足造成系统多任务运算错误&#xff1a; 虚拟内存是Windows系统所…

(免费分享)基于springboot健康运动-带论文

源码获取&#xff1a;关注文末gongzhonghao&#xff0c;输入013领取下载链接 ​开发工具&#xff1a;IDEA, mysql5.7 技术&#xff1a;springbootmybatis-plus 健康管理包括&#xff1a;健康体检、健康评估、健康促进和健康服务四大部分。具体来说健康管理就是由健康管理顾问…

13.4 GAS与攻击

目录1. 由GA砍出的第一刀2. 挥剑时的命中检测3. 完善&#xff1a;UI显示当前血量参考&#xff1a;1. 由GA砍出的第一刀 有了前面章节的经验&#xff0c;我们可以很容易创建一个专用于攻击的GA&#xff1a; 其中PlayMontageAndWait任务节点负责攻击动画及相应回调的绑定。 但是…

向毕业妥协系列之深度学习笔记(二)深层神经网络

目录 一.深层神经网络 二.前向和反向传播 三.深层网络中的前向传播 四.核对矩阵的维数 五.为什么使用深层表示 六.参数VS超参数 一.深层神经网络 就是好多层。 二.前向和反向传播 三.深层网络中的前向传播 四.核对矩阵的维数 略 五.为什么使用深层表示 我们都知道深度…

在淘宝开店后,如何发布宝贝?从哪发布?

近期&#xff0c;有几位在淘宝新开店的店主&#xff0c;来向我们咨询了一些问题&#xff0c;总结来说可以将问题归为一个&#xff1a;在淘宝开店后&#xff0c;怎样上传宝贝&#xff1f;从哪上传&#xff1f;下面&#xff0c;小编来给大家简单的说一下发布宝贝时要注意什么&…

AD域 - 自动为域颁发证书

自动为域用户颁发数字证书 ———————————— 进入CA证书颁发机构 在“证书颁发机构”窗口中,鼠标右键点击“证书模板”,在弹出的快捷菜单中点击“管理” 在“证书模板控制台”窗口中,鼠标右键点击右侧列表中的“用户”,在弹出的快捷菜单中点击“复制模板

【Redis】Redis数据库的实现原理

在之前的文章我们介绍过&#xff0c;Redis服务器在启动之初&#xff0c;会初始化RedisServer的实例&#xff0c;在这个实例中存在很多重要的属性结构&#xff0c;同理本篇博客中介绍的数据库实现原理也会和其中的某些属性相关&#xff0c;我们继续看一下吧。 1.服务器和客户端…

【设计模式】 - 创建者模式 - 原型模式

目录标题1. 原型模式1.1 概述1.2 结构1.3 实现1.4 浅克隆Demo1&#xff1a;基本类型Demo2&#xff1a;引用类型浅克隆总结&#xff1a;1.5 深克隆实现方式1&#xff1a;浅克隆嵌套1. Address类实现Cloneable接口&#xff0c;重写clone方法;2. 在Customer类的clone方法中调用Add…

[附源码]SSM计算机毕业设计智慧教室预约JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

2019年1+X 证书 Web 前端开发中级理论考试——易错题、陌生但又会考到的题目原题+答案

文章目录 &#x1f3af;关于1X标准 &#x1f3af;关于中级考点 ❗❗❗注意&#xff1a; 理论题题型包括单选题、多选题、判断题。 ❗注意&#xff1a;题目序号没有修改 ❗红色的选项才是正确答案 ❗如果题目后面没有红色的选项&#xff0c;那么括号里面的答案是正确的 …

Unity游戏Mod/插件制作教程01 - BepInEx的安装和使用

前言 本章节为没有使用过BepInEx的同学进行BepInEx的安装和使用方面的介绍&#xff0c;如果你之前已经使用过并了解如何使用&#xff0c;可以直接跳过本章节。 BepInEx下载 BepInEx的Github链接 https://github.com/BepInEx/BepInEx/releases 一共有3种版本&#xff0c;BepIn…

Hive环境搭建

3.1 Hive环境搭建 3.1.1 Hive引擎简介 Hive引擎包括&#xff1a;默认MR、tez、spark Hive on Spark&#xff1a;Hive既作为存储元数据又负责SQL的解析优化&#xff0c;语法是HQL语法&#xff0c;执行引擎变成了Spark&#xff0c;Spark负责采用RDD执行。 Spark on Hive : Hi…

人人开源后台项目maven构建(yyds)

人人开源后台项目maven构建(yyds) npm run serve 和 npm run dev 的区别在日常运行vue 项目中 在终端 运行命令有时用到 npm run serve 有时是 npm run dev。那么&#xff0c;什么时候用到 serve &#xff0c;什么时候用到 dev 呢&#xff1f; 他们的区别是什么&#xff1f;一…

【学习笔记】《Python深度学习》第四章:机器学习基础

文章目录1 机器学习的四个分支1.1 监督学习1.2 无监督学习1.3 自监督学习1.4 强化学习2 评估机器学习模型2.1 训练集、验证集和测试集2.2 注意事项3 数据预处理、特征工程和特征学习3.1 神经网络的数据预处理3.2 特征工程4 过拟合与欠拟合4.1 减小网络大小4.2 添加权重正则化4.…