Qt备忘录之一:中文字符串处理
- 再创世纪·代码厨房
- 2015-02-25
- 264热度
- 0评论
由于工作上的需要,近期开始学习Qt。学习的心得将陆续、不定期地进行更新。也欢迎各位朋友前来指正。
目前顾毅用的是VS+QtPlugIn,Qt版本为4.8.6。
在Qt中新建一个工程,在main.cpp中写入以下代码:
[code lang="cpp" collapse="false"]
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel *label = new QLabel("中文");
label->show();
return a.exec();
}
[/code]
直接编译出来的结果如下所示:
显见是编码不正确,这个问题在刚接触VC++的时候也头疼了挺久。在网上查了一下资料,无非是使用setCodecForXXX()和tr()这两种方法。
setCodecForXXX()解析:
这一系列的函数有三个,分别是:
[code lang="cpp" collapse="false"]
void QTextCodec::setCodecForCStrings(QTextCodec *<i> codec</i>)
void QTextCodec::setCodecForTr(QTextCodec *<i> codec</i>)
void QTextCodec::setCodecForLocale(QTextCodec *<i> codec</i>)
[/code]
这三个函数分别用于设置QString、tr和本地语言环境的编码格式。对应的,以下三个则是获取当前使用中的编码格式:
[code lang="cpp" collapse="false"]
QTextCodec* QTextCodec::codecForCStrings()
QTextCodec* QTextCodec::codecForTr()
QTextCodec* QTextCodec::codecForLocale()
[/code]
使用以上的三对方法,可以实现对字符串编码的指定和获取。Qt支持的文字编码大约有50种,详情可参考官网上的说明(http://qt-project.org/doc/qt-4.8/QTextCodec.html)。其中,简体中文可以使用名称“GBK”或者“GB18030”或者“GB2312”作为编码名称来指定。在Qt平台中,这三种编码将不作区分。指定编码格式的示例如下:
[code lang="cpp" collapse="false"]
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030"));
[/code]
如果不清楚本地系统采用什么编码,也可以使用如下的语句以保证编码与本地系统相匹配:
[code lang="cpp" collapse="false"]
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
[/code]
或者
[code lang="cpp" collapse="false"]
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("SYSTEM"));
[/code]
通过强制指定编码格式,可以实现中文字符串的本地正确显示,却不能保证编译出来的程序在其他电脑上也能正确展现。因此使用setCodecForXXX()并不是合适的解决方案。
tr()是什么?
根据Qt的官方文档(http://doc.qt.io/qt-4.8/qobject.html#tr),tr()的原型是:
[code lang="cpp" collapse="false"]
QString QObject::tr char * sourceText, const char * disambiguation = 0, int n = -1)
[/code]
官方的说明如下:
Returns a translated version of sourceText, optionally based on a disambiguation string and value of n for strings containing plurals; otherwise returns sourceText itself if no appropriate translated string is available.
也就是说,tr()的作用是把sourceText的“翻译版本”返回,这个翻译结果是根据“消歧义字串”disambiguation和“复数”n得出,如果没有找到对应的翻译结果,将原值返回。
csdn的dbzhang800之前写过文章,详细的解析了tr()的调用过程,顾毅不再赘述,请点击原文(Qt中translate、tr关系 与中文问题)查阅。根据dbzhang800的分析,我们可以知道,最终执行的函数实际是:
[code lang="cpp" collapse="false"]
QString QCoreApplication::translate(const char * context, const char * sourceText, const char * disambiguation = 0, Encoding encoding = CodecForTr)
[/code]
因此,tr()实际上也是需要指定一个编码规则的(通过void QTextCodec::setCodecForTr(QTextCodec * codec)进行设定;如未设定,将默认使用ASCII)。所以,QString str = tr("中文");这种使用方法,也可能产生问题。
tr()推荐的用法是“翻译”,因此可以考虑将程序中的字串用英文表示,再在翻译文档中转换为中文。这样可以从根本上解决中文字符串在程序中的显示问题。
二零一五年二月廿五日
顾毅写于厦门