QString 乱谈(3)-Qt5与中文

转载 2016年08月28日 15:25:52
 

QString 乱谈(3)-Qt5与中文

标签: qt编译器characterwindows跨平台codec
 23201人阅读 评论(6) 收藏 举报
 分类:
 

目录(?)[+]

今天,随着Change QString's default codec to be UTF-8 进入Qt5的master分支,我们总算可以重新审视一下Qt的中文支持问题。

20120516更新:建议阅读QtCore模块维护者Thiago Macieira 的文章 Source code must be UTF-8 and QString wants it 

没有了setCodecXXX的Qt5

  • Qt5假定的执行字符集是UTF8,不再允许用户擅自改动。这样一来,Qt4中setCodecXXX的各种副作用不再存在,而且中文问题更为简单。

QString s1 = "汉语";
QString s2("漢語");
QString s3 = tr("中文")
QString s4 = QStringLiteral("中文");//只要字符串不需要翻译,请关注这个
QString s5 = QString::fromWCharArray(L"中文");
QString s6 = u8"中文";//C++11
QString s7 = tr(u8"中文")
...

所有这些在Qt5默认都会正常工作,唯一要求就是:确保你的C++的执行字符集(the execution character set)是UTF-8

各种写法PK?

简单不一定好

最简单直接的用法,当属:

QString s1 = "汉语";
QString s2("漢語");
QString s6 = u8"中文";//C++11
...

这有什么问题呢?

  • 定义宏QT_NO_CAST_FROM_ASCII之后,上述代码无法将通过编译(对了,这个宏似乎应该改个名字才对,叫QT_NO_CAST_FROM_CSTRING会名副其实一些)

被误用最多的

在Qt4中,QObject::tr()是被滥用(误用)的函数之一:

QString s3 = tr("中文")
...

原因:

  • 在Qt4,不少用户被铺天盖地的setCodecForTr()所影响,进而靠它来解决中文问题。

它的用途是用来进行翻译(I18N和L10N)的,如果你没有这方面的需求,真的没必要用它。(在Qt4中,我只注意到有2个大陆网友和1个日本网友有需求并真正进行过这方面的尝试,那么其他应该算误用吧?)

让人困惑的wchar_t

刚开始接触Qt和QString时,曾多次想过,为什么不用wchar_t,为什么,...

QString s5 = QString::fromWCharArray(L"中文");

这个东西在Windows下真的很有用:首先它是Windows系统API所用字符串,其次它和QString内部表示相同。但是由于MSVC处于种种考虑,鼓励大家使用TEXT/_T,反倒使大家对它比较陌生。

但是从C++标准来说,wchar_t毕竟不是char16_t,所以跨平台性不好。在linux下,这行代码需要utf32到utf16的转换。

QStringLiteral

这是一个宏,一个蛮复杂的宏:

QString s4 = QStringLiteral("中文");

之前?

在介绍这个宏之前,我们先看看下面写法有什么劣势:

QString s1 = "汉语";
QString s2("漢語");
QString s3 = tr("中文")
QString s6 = u8"中文";//C++11
...

首先,2个汉字的字符串以UTF-8编码的形式被编译器放到了常量区。(至少占7个字节吧?)

然后,程序运行时,构造QString实例,需要在堆上申请空间,存放utf16格式的相应字符串。

有没有存在浪费?

方案

QString 内部是UTF16,如果C++编译器在编译期直接提供了UTF16的字符串,那么我们在QString内部直接保存也就够了。这样

  • 省掉存在两份不同的拷贝(即相应的转换,malloc的成本)
  • 对汉字来说,UTF16本身就是UTF8省空间

现实

目前,我们还没有可靠的方式在C++使用UTF16的执行字符集(the execution character set)。

  • 尽管 L"..."(wchar_t*) 在Windows下是UTF16,但是不具备跨平台性。
  • C++11可以保证这一点,u"..."(char16_t),但主流编译器尚未提供完美支持。

这两点,导致了QStringLiteral的复杂性

实现

源码见 qtbase/src/corelib/tools/qstring.h

(代码中使用宏、模板、lambda表达式,还是相当复杂的,此处只摘片段)

  • 如果编译器支持char16_t,则直接使用

#define QT_UNICODE_LITERAL_II(str) u"" str
typedef char16_t qunicodechar;
...
  • 否则。如果在Windows平台下,或者在其他的wchar_t宽度为2的环境下,使用wchar_t

#if defined(Q_CC_MSVC)
#    define QT_UNICODE_LITERAL_II(str) L##str
#else
#    define QT_UNICODE_LITERAL_II(str) L"" str
#endif
typedef wchar_t qunicodechar;
...
  • 否则。编译器不支持,Qt作为一个库,肯定也没有办法

# define QStringLiteral(str) QString::fromUtf8(str, sizeof(str) - 1)

相关文章推荐

QString 乱谈(3)-Qt5与中文

原文链接:http://blog.csdn.net/dbzhang800/article/details/7542672 两个月前,简单写过QTextCodec中的setCodecF...

QString 乱谈(3)-Qt5与中文

两个月前,简单写过QTextCodec中的setCodecForTr等终于消失了 (Qt5) ,在Qt论坛上,不少用户都对去掉这两个函数表示特别的不了解。为什么会这样?我想多少能说明不少用户对C+...

QT中QString类中文详解

  • 2012-07-06 16:04
  • 34KB
  • 下载

Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK 乱码与转码问题

代码如下:如果不不设全局的字符集是utf-8,那么网上一般的方法是可以转的。如下程序中 #define DD 1的情况下;但是如果设置了全局的utf-8,再用以前的方法: QByteArra...

QT:QString 字符串和中文字符编码

QString 字符串和中文字符编码 QT内部的编码方式 Unicode (utf-16) linux平台默认使用:utf-8 windows平台默认使用:gbk2312/gbk/gbk18030 ...

QT QString与中文问题

首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。[喝小酒的网摘]http://blog....

Qt QString 中文 char* UTF-8 QByteArray QTextCodec unicode gb2312 GBK

#include #include #include #include void MainWindow::on_pushButton_clicked() {        /* ...

Qt 常用类(3)—— QString

QString 类是 Qt 中用于表示字符串的类,实现在 QtCore 共享库中。QString 类在实现上有以下特征。       1)字符串采用 Unicode 内部编码,可以表示世界上大多数语...

QString 与中文问题/Qt界面中文字体及大小设置

(更新:本文的姊妹篇 Qt中translate、tr关系 与中文问题) 原文:http://hi.baidu.com/cyclone/blog/item/9d7293130e5a498d6538db...
  • zzk197
  • zzk197
  • 2012-03-20 10:48
  • 4386

QString 乱谈(1)

一个月前尝试写了一篇关于QStringLiteral,存盘时MoinMoin罢工了。吸取一点经验,还是写成短篇吧 可是,可是,QString不就是简简单单一个字符串么?能有什么可谈的。真的么.....
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)