QT 的国际化支持操作要点.

----------------------------------------
author: hjjdebug
date: Fri Aug 14 13:11:15 CST 2020
----------------------------------------
本篇文章帮助你理解如下几个问题:
1. 翻译过程是如何进行的?
2. 翻译的上下文是指的什么?
3. 如何使用QT_TR_NOOP, QT_TRANSLATE_NOOP
4. QObject::tr() 是如何工作的.
5. lupdate 工具是如何工作的.

6. 如何提取宏定义中的字符串? 也就是说宏定义中字符串如何支持国际化?
7. 类中字符串如何支持国际化.
8. 全局变量引用字符串如何支持国际化.

如果你以上问题都明白,那就不用把玩了,或者简单阅读一下代码也能温故而知新.

$cat main.cpp

#include <QtGui>
#include "macro.h"
#include "classTest.h"

const char *pStr =  QT_TRANSLATE_NOOP("mygroup","中文1");
//const char *pTest =	QT_TR_NOOP("中文3"); // lupdate 提示: tr() cannot be called without context
//如下定义虽然可编译,可提取,但执行时会显示乱码,不能完成翻译工作. 
//因为此时tr()还没有初始化(QTextCodec::setCodecForTr(g_utf8)), 会按默认的iso8859工作.
//QString gStr = QObject::tr("中文2");  
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	QTextCodec *g_utf8 = QTextCodec::codecForName("utf8");
	QTextCodec::setCodecForTr(g_utf8); //设置tr 的输入编码为utf8


	QTranslator *tranlator=new QTranslator;           	//创建翻译器
	tranlator->load("src_fr.qm");    		//加载语言包
	a.installTranslator(tranlator); 	//安装翻译器
	QPushButton *p = new QPushButton(QObject::tr("中文3"));
	p->show();
//	qDebug() << "gStr:"<<gStr<<endl;
	QString str=a.translate("mygroup",pStr);
	qDebug()<<"language:"<<str<<" "<<endl;

	QString str2=QObject::tr("中文4");
	qDebug()<<"language:"<<str2<<" "<<endl;
	classTest atest;
	return a.exec();
}

其它辅助代码:

hjj@hjj-Inspiron:~/tr_research$ cat macro.h 
#ifndef _MACRO_H
#define _MACRO_H
#define OPENFILE_FAIL(fn) \
		MyMessageBox::warning(NULL,QObject::tr("信息"),QObject::tr("文件<%1>读打开失败.").arg(fn),QObject::tr("确定"));
#endif
hjj@hjj-Inspiron:~/tr_research$ cat classTest.h
#ifndef _CLASS_TEST_H
#define _CLASS_TEST_H
#include <QObject>
class classTest : public QObject
{
Q_OBJECT
public:
	static const char *pTest2;
	classTest();
	virtual ~classTest(){};
};

#endif
hjj@hjj-Inspiron:~/tr_research$ cat classTest.cpp 
#include <QDebug>
#include "classTest.h"
const char* classTest::pTest2 = NULL;
classTest::classTest()
{
 	pTest2 = QT_TR_NOOP("中文5"); // QT_TR_NOOP 要求必须在一个类里面. 这个"类名"就是上下文, 要调用tr()所以继承QOjejct类
	qDebug()<<tr(pTest2);
}

通过对该代码的把玩,我有如下体会:


1. QT_TR_NOOP, QT_TRANSLATE_NOOP 是什么?
答,是两个宏
#define QT_TR_NOOP(x) (x)
#define QT_TRANSLATE_NOOP(scope, x) (x)

它们只是起一个标记作用,供lupdate 来识别提取出字符串.

2. 类中定义的tr 是调用的哪个函数?
答: QObject::tr() 最后也是调用的QApplication::translate(), 其上下文是QObject.

3. 自定义翻译上下文. 就像程序实例中使用的那样.
    "mygroup" 就是我自定义的上下文
    const char *pStr =  QT_TRANSLATE_NOOP("mygroup","中文2");

4. 注意事项:
    a. ts文件中文字符是乱码, 你应该在工程文件中指明CODECFORTR是utf8格式
    即在.pro中加下面一句.
    CODECFORTR=utf8
    这样,lupdate 就不会把源当成iso8859来抓取字符串了.

     b. 当你想翻译成法文而不是翻译成默认的英文时, 你只要把ts文件的语言选项改一下就可以了.
        <TS version="2.0" language="en">
        改成
        <TS version="2.0" language="fr">


5. 翻译过程是如何进行的?
    a. lupdate <project>
        project 要有一句类似 TRANSLATIONS += src_fr.ts , 这样生成的翻译源文件会是src_fr.ts
        它会提取工程中的被tr包围的字符串(主要的),以及被QT_TR_NOOP, QT_TRANSLATE_NOOP
        包围的字符串, 这些字符串都是有上下文的, tr,QT_TR_NOOP 的上下文就是类名, QT_TRANSLATE_NOOP的上下文是自定义的.

         如果在宏中定义了字符串(最好避免这样操作). 实在不行,应该用QT_TRANSLATE_NOOP 来包围,
        用QObject::tr()也可以,但你应该明白你在做什么.
        因为lupdate 并不是编译器, 它不会把宏在调用处展开再提取, 而是直接提取.
    b. linguist src_fr.ts
        翻译的源文件<例如src_fr.ts> 是一个xml 文件, 指明了源文件位置.
        需要手工翻译成对应的字符串.

    c. lrelease <project>
        将定义的源文件<例如src_fr.ts> 翻译成对应的二进制文件<src_fr.qm>
        我看了一下qm 二进制文件,
        翻译的规则是去掉了位置信息,保留了上下文及源字符串,目的字符串信息.
         由此可知,当满足上下文及源字符串时,即被翻译成目的字符串. 否则不翻译!
        .qm 就像是一个数据库, 它的输入条件是上下文和源字符串,输出是目的字符串.

工程是QT4 下的,要想在QT5 下编译通过, 需做如下修改, 哎!下载地址上不让我修改! 潦记于此:

若在QT5 下编译:

问题1, ‘QApplication a’ has initializer but incomplete type

原因: 缺少包含的头文件
解决办法, 在main.cpp 中添加 "#include <QApplication>"

问题2, fatal error: QApplication: 没有那个文件或目录

原因: 缺少包含的路径
解决办法,修改pro 文件,添加 "QT+=widget", 使包含指定目录  解决

问题3, error: ‘setCodecForTr’ is not a member of ‘QTextCodec’

原因:QT5 已取消该接口
解决办法: 注释掉即可

问题4:  ‘QPushButton’ was not declared in this scope

原因: 缺少包含的头文件
解决办法, 在main.cpp 中添加 "#include <QPushButton>"


小结: Qt4 中包含了QtGui 就相当于包含了QApplication, QPushButton 等头文件,
但在QT5 中, 这些头文件都挪到了QtWidget目录下, 所以包含的头文件要修改, pro文件也要修改.

Qt4代码工程可以到csdn上下载, 链接地址:

https://download.csdn.net/download/hejinjing_tom_com/12712534个

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值