Qt中translate、tr关系 与中文问题

Qt中translate、tr关系 与中文问题
2010-09-22 00:15

题外话:何时使用 tr ?

在论坛中漂,经常遇到有人遇到tr相关的问题。用tr的有两类人:

  • (1)因为发现中文老出问题,然后搜索,发现很多人用tr,于是他也开始用tr
  • (2)另一类人,确实是出于国际化的需要,将需要在界面上显示的文件都用tr包起来,这有分两种:
    • (2a) 用tr包住英文(最最推荐的用法,源码英文,然后提供英文到其他语言的翻译包)
    • (2b) 用tr包住中文(源码用中文,然后提供中文到其他语言的翻译包)

注意哦,如果你正在用tr包裹中文字符,却不属于(2b),那么,这是个信号:

  • 你在误用tr
  • 你需要的是QString,而不是tr

如果你确实属于(2b),请做好心理准备,你可能还会遇到很多困难,请考虑Qt国际化(源码含中文时)的点滴分析

tr 是做什么的?下面二者的区别是什么?

QString text1 = QObject::tr("hello");QString text2 = QString("hello");

tr是用来实现国际化,如果你为这个程序提供了中文翻译包(其中hello被翻译成中文"你好"),那么text1的内容将是中文"你好";如果你为程序提供且使用日文翻译包,那么text1的内容将是日文。

tr是经过多级函数调用才实现了翻译操作,是有代价的,所以不该用的时候最好不要用。

关注的对象

本文关注的是tr或translate中包含中文字符串的情况:

  • QObject::tr()

  • QCoreApplication::translate()

  • QTextCodec::setCodecForTr

这个问题本多少可说的。因为涉及到的编码问题和QString 与中文问题中是完全一样的,只不过一个是用的setCodecForCStrings一个用的是setCodecForTr。

简单回顾QString的中文问题

  • QString 采用的unicode,在中文支持上不存在任何问题
  • "我是中文" 这是传统的 const char * 的窄字符串

  • 当将窄字符串赋值到QString时,我们需要告诉它我们的窄串采用的何种编码(gbk?、utf-8?)
  • 究竟何种编码主要取决于我们的源代码文件的编码(windows上一般是gbk,其他平台一般utf-8)

例子:

QString s1 = "我是中文";
QString s2("我是中文");
QString s3;
s3 = "我是中文"
  • s1、s2 用的是QString的构造函数QString ( const char * str )

  • s3 用的是QString的赋值操作符 QString & operator= ( const char * str)

如果不指定编码,s1,s2,s3将全部都是(国内大多数人所称的)乱码。因为QString将这些const char *按照latin1来解释的,而不是用户期待的gbk或utf8。

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"))

这两条语句中的一条可以解决问题,至于如何选择,此处不再重复。

QObject::tr

说实话,在tr中使用中文不是个好主意。不过既然总有人用(无论是(1)还是(2b)),而且总有人遇到问题,所以还是简单整理一下吧。

相比QCoreApplication::translate,大家用tr应该用的很多了,尽管不少人不清楚tr究竟是做什么的^_^

tr("我是中文");

这调用的是下面这个函数(至少我们可这么认为是)。

QString QObject::tr ( const char * sourceText, const char * disambiguation = 0, int n = -1 )

与QString("我是中文")完全一样,你必须告诉tr这个窄字符串是何种编码?你不告诉它,它就用latin1。于是所谓的乱码问题就出来了。

如何告诉tr你写的这几个汉字在磁盘中保存的是何种编码呢?这正是

QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")); 
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));

所做的。这两个选择的原则,由于和前文完全一样,此处也不再重复。

如果你的编码采用的utf8,可以直接使用trUtf8而不必设置setCodecForTr。

如果你只关心乱码问题,到此为止就可以了(下面不再关注编码)。如果想对tr进一步了解,不妨。。继续。。

QCoreApplication::translate

我们知道tr是用于实现程序的国际化(或者说多语言翻译),看Qt相关资料的话,我们知道实现该功能的还有下面这个函数:

QString QCoreApplication::translate ( const char * context, const char * sourceText, const char * disambiguation, Encoding encoding, int n )

其实,这个才是真正进行翻译操作的函数,前面我们提到的tr最终是通过调用该函数来实现翻译功能的(稍后我们会看tr是如何调用translate的)。

对tr和这个函数,manual中都有比较详尽的解释。我们这儿简单看一下它的这几个参数:

  • context 上下文,一般就是需要翻译的字符串所在的类的名字
  • sourceText 需要翻译的字符串。(我们关注的编码其实就是它的编码)
  • disambiguation 消除歧义用的。(比如我们的类内出现两处"close",一处含义是关闭,另一处含义是亲密的。显然需要让翻译人员知道这点区别)
  • encoding 指定编码。它有两个值
    • CodecForTr 使用setCodecForTr()设置的编码来解释 sourceText

    • UnicodeUTF8 使用utf8编码来解释 sourceText
    • 其实这两个分别对应tr和trUtf8
  • n 处理单复数(对中文来说,不存在这个问题)

tr与translate

这两个函数的说明,一个在QObject的manual,另一个在QCoreApplication的manual中。

介绍一下tr与translate的关系。前面提到了,tr调用的是translate。如果仅仅这样一说,没有证据,还真难以让大家相信。好吧,继续

tr 在何处定义

你可能说:这不废话吗,manual中写得明白的,它是QObject的静态成员函数。而且还有源码为证:

//来自 src/corelib/kernel/qobject.h 
#ifdef qdoc 
static QString tr(const char *sourceText, const char *comment = 0, int n = -1);
static QString trUtf8(const char *sourceText, const char *comment = 0, int n = -1);
#endif

嘿嘿,差点就被骗了,发现没:它们被预处理语句包住了。

这说明了什么呢?说明了这段代码仅仅是用来生成Qt那漂亮的文档的(qdoc3从代码中抽取信息,生成一系列的html格式的manual)。

啊,也就是说,这是假的。那么真正的定义呢??在一个大家都很熟悉的地方,猜猜看?

这就是

Q_OBJECT

该宏的定义在src/corelib/kernel/qobjectdefs.h中

#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

#  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); }

现在看到:tr调用的是 staticMetaObject对象的tr函数,staticMetaObject 的定义在moc生成的 xxx.moc 或 moc_xxx.cpp 文件内(你随时可以验证的)。

staticMetaObject 是一个 QMetaObject 类的实例,我们继续看一下该类的源码:

/*!\internal 
*/QString QMetaObject::tr(const char *s, const char *c) const{return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::CodecForTr);
 }
 /*!
 \internal 
*/ 
QString QMetaObject::trUtf8(const char *s, const char *c) const 
{     
return QCoreApplication::translate(d.stringdata, s, c, QCoreApplication::UnicodeUTF8); 
}

至此,我们应该都看清楚了。我们的 Q_OBJECT 宏展开后为生成 tr ,tr调用QCoreApplication的translate函数。而该函数需要指定编码。

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

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

相关文章

html打印边距影响内容大小,关于web打印的问题,如何控制纸张大小和页边距

关于这个问题我上网查了很多资料,最后参照一个资料。编写了下面内容:但是根本达不到要求,哪位大侠有真正使用的经验?告诉我到底应该怎样弄?求一个真正使用的方法,谢谢!再就是这一行在visual stu…

win32控制台

可回显的调用方法: 这个方法步骤比较复杂,是通过创建一个新进程来模拟cmd命令行,将写命令行和回显通过管道的方式呈现。 例如: view plain 1. void CTestMFCDlg::OnOK() 2. { 3. // TODO: Add extra validation …

html是前段还是后端,javascript属于前端还是后端?

JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。前端开发和后端开发的区别在于&#xff1a…

ubuntu12.04中shell脚本无法使用source的原因及解决方法

现象: shell脚本中source aaa.sh时提示 source: not found 原因: ls -l which sh 提示/bin/sh -> dash 这说明是用dash来进行解析的。 改回方法: 命令行执行:sudo dpkg-reconfigure dash 在界面中选择no 再ls -l which sh 提…

2021年河北省高考成绩录取查询结果,2021年河北高考一本录取结果查询和录取通知书发放时间...

河北高考一本录取结果查询和录取通知书发放时间从河北教育考试院获悉,河北高考成绩查询时间已经确定。同时,考生、家长关心的各批次录取时间也已出炉。其中,本科一批高等学校录取时间安排如下:本科一批第一志愿录取结束时间为7月1…

viewgroup 渲染过程

参考 http://blog.csdn.net/luoshengyang/article/details/8372924 总体步骤 performTraversals-->measure---->layout----->draw 测量布局渲染 1.measure 测量过程 例子:FrameLayout measure 测量开始判读是否需要测量 onMeasure 求实际宽度 measureChi…

C++读取ini文件的类

C读取ini文件的类 取自:http://www.viksoe.dk/code/all_mfc.htm,里面有各种MFC常用的类 // Ini.h: interface for the CIni class. // // Written by Bjarke Viksoe (bjarkeviksoe.dk) // Copyright (c) 2000. // // This code may be used in compiled …

A20(emmc) 编译环境

1. 需要物理内存3G,或者调高虚拟内存,否则编译会报错(killed) 2. 安装jdk 3. apt-get install bison apt-get install flex apt-get install gperf apt-get install libswitch-perl apt-get install libxml2-utils

Linux查看设置系统时区

关于时区的概念,其实初中地理课已经涉及,很多人都多少了解一些,可能只是细节搞不太清楚。为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总比西边的早。东边…

SQL基础问题整理

在程序中,数据库操作是必不可少的部分,所以我们要备足数据库相关知识才能去应付程序中出现的种种问题。基于此,我特地在国外网站、博客上整理了一些问题,并附带了答案和解释、参考。为了保证“原汁原味”,我就保留了英…

计算机突然从桌面消失了,电脑桌面突然什么都没有了,怎么处理

★桌面-点击鼠标右键-点击排列图标-点击显示桌面图标★在桌面上右键点击→“属性”→桌面项→左下有个“自定义桌面”进入设置,把你需要的桌面项目打上勾,然后确定就行了。★先按ctrlaltdel三键打开任务管理器&#xf…

V210 时区

V210默认时区是格林尼治时间,只要把ubuntu的/etc/localtime文件拷贝到板子上就可以了 用date -R可以看到时区是否正确

腾讯或联姻优酷,微信嫁女模式引发互联网通婚潮流

据消息称:腾讯在前段时间联姻京东后有可能继续做甩手掌柜,这回要甩的是腾讯视频。 前几年,最火爆的电商业务除了电商外,再者一个就是视频业务了。 不知道大家还记得优酷当时的崛起之初的情景么?我来罗列一下: 1、 大…

微型计算机键盘上的西服的间称为,一台完整的微型计算机主要由主机箱. .键盘.鼠标及音箱.打印机组成....

阅读下面的文字,完成后面题目。(25分)“博客之父”方兴东(节选)打开百度,输入“方兴东’’搜索,100多万条信息赫然呈现。罩在方兴东头上的光环颇多:清华大学博士、专栏作家、互联网评论家……而“中国博客之父”的称号&#xff0c…

mplayer

mplayer -af volume20 *.mp3 经测试,volume在-50和50这个区间就可以了,0最佳,超过0就爆音

[翻译] 学习iOS开发的建议:如何从菜鸟到专家

[文章原地址] http://mobile.tutsplus.com/tutorials/iphone/ios-quick-tip-from-novice-to-expert/ 翻译有误之处请勿见笑,本人将在文章的部分地方添加注释,并根据需求增减文章内容,在此对原作者辛勤劳作表示感谢 iOS Quick Tip: From Novi…

计算机工程与应用查重吗,计算机工程期刊录用率_计算机工程与应用期刊_计算机八大核心期刊...

《计算机工程》杂志怎么样都是各高校开设的课程也不尽相同,但学习深度和侧重点不一样。计算机科学期刊写人脸检测的录取率高吗计算机专业发一篇sci相对比较容易,所以必须看你在那个杂志上发表,下面最顶级的也就是计算机一区的期刊&#xff0c…

如何将多个源文件编译为一个.ko

陆陆续续也写了几个Linux内核模块了,但每次都是把代码写在一个源文件中,上次尝试了写在两个.c文件中,结果没有编译通过。 无奈之下,将其中一个.c文件重命名成.h文件,再include当另一个当中。但是,在.h文件中…

未来计算机将具有图像识别 定理证明,[单选] 低温计与高温计所测温度的分界线为()。...

[单选] 低温计与高温计所测温度的分界线为()。更多相关问题【单选题】向一个栈顶指针为 HS 链式栈中插入一个 s 所指结点时,则执行( )。A. HS next s ; B. s nextHS next ; HS nexts ; C.【判断题】每年10月是青海湖观鸟的最好季节。【单…

[nodejs]国内npm安装nodejs modules失败的几个解决方案

使用npm安装node模块时经常有卡住安装失败的情况,如图所示。原因在于npm服务器在美国,还有就是某强大的防火墙作用。这样的问题导致很多新手放弃使用node,几乎每天都有新手再问这个问题。现在分享一下解决这个问题的解决方案 1.可以通过一劳永…