原文地址http://blog.csdn.net/dbzhang800/article/details/7542672?reload

两个月前,简单写过QTextCodec中的setCodecForTr等终于消失了 (Qt5) ,在Qt论坛上,不少用户都对去掉这两个函数表示特别的不了解。为什么会这样?我想多少能说明不少用户对C++中源码字符集和执行字符集的不太了解,从而造成对这种函数的依赖或误用。

今天,随着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与中文的更多相关文章

  1. QString 乱谈(3)-Qt5与中文

    原文请看:http://blog.csdn.net/dbzhang800/article/details/7542672 两个月前,简单写过QTextCodec中的setCodecForTr等终于消失 ...

  2. QString 乱谈(1)

    一个月前尝试写了一篇关于QStringLiteral,存盘时MoinMoin罢工了.吸取一点经验,还是写成短篇吧 可是,可是,QString不就是简简单单一个字符串么?能有什么可谈的.真的么... ( ...

  3. QString乱谈(2)

    长期以来,很多人都清楚,一旦C++源码中直接使用了中文,这样的源码想要跨平台(I18N)会非常困难. 随着: Windows下:MSVC2010成为主流 Linux下:GCC升级到4.6 C++中的中 ...

  4. C++矢量图形库系列(1)——矢量图形库乱谈(转)

    转自:http://blog.sina.com.cn/s/blog_4265e1760100lg03.html 本系列篇章的主要内容是讲解矢量图形库的编译.开发和使用.并不对他们周边的内容做过多的描述 ...

  5. VS2013+QT5.3 中文乱码和中文路径不识别

    http://blog.csdn.net/brave_heart_lxl/article/details/7186631 ubun图中文乱码 https://blog.csdn.net/u013007 ...

  6. JIT-动态编译与AOT-静态编译:java/ java/ JavaScript/Dart乱谈

    C 和 C++ 之类的编译语言性能远超Java,但是生成的代码只能在有限的几种系统上执行,这就有了Java的存在基础(JVM-跨平台) 早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之 ...

  7. 微软ASP.NET技术“乱谈”

    微软ASP.NET技术“乱谈” 2014新年了,顺手写的一点文字,主要谈谈我对当前微软ASP.NET技术的看法,比较随意,大伙儿随便看看吧. 1 当前微软Web平台技术全貌 从2002年发布.NET ...

  8. 优测优社区干货精选|老司机乱谈编辑器之神——vim

    文 / 腾讯 吴双 前言 优测小优 有话说: 腾讯优测只有应用测试大神?不不不,我们还有各种研发大牛! *** vim 是一种信仰,我自从2004年有了这个信仰,已经12个年头了.本文介绍了学习vim ...

  9. [转]vnpy乱乱谈 02架构

    vnpy乱乱谈 02架构 转自:http://101.132.65.227/?p=51 听到架构这个词先不要害怕. 其实这部分内容还是挺简单的. 一般而言, 一个交易系统我们可以简单的分成输入, (系 ...

随机推荐

  1. Unexpected namespace prefix "xmlns" found for tag Linear Layout

    原文地址http://blog.csdn.net/taxuexumei/article/details/41523419 今天遇到的问题,,,保存到博客里,下回遇到找博客就行了,,,,,, 今天在制作 ...

  2. atitit.js 各版本 and 新特性跟浏览器支持报告

    atitit.js 各版本 and 新特性跟浏览器支持报告 一个完整的JavaScript实现是由以下3个不同部分组成的 •核心(ECMAScript)--JavaScript的核心ECMAScrip ...

  3. java集合练习——题目

    2.已知有十六支男子足球队参加2008 北京奥运会.写一个程序,把这16 支球队随机分为4 个组.采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷 ...

  4. Windows Error Code(windows错误代码详解)

    0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒绝访问. 6 句柄无效. 7 存储控制块被损坏. 8 存储空间不足,无法处理此 ...

  5. 为ubuntu操作系统增加root用户

    1:当安装好虚拟机,安装好Ubuntu操作系统后,登陆的时候发现除了自己的设置的用户就是外来用户,其实Ubuntu中的root帐号默认是被禁用了的,所以登陆的时候没有这个账号,但是如果每次使用root ...

  6. 更改Windows系统的密码之后,SQL Server 2008服务无法启动

    问题:更改Windows操作系统的密码之后,SQL Server 2008服务无法启动. 原因:SQL Server服务需要使用操作系统的某个登录账户. 解决:需要在服务的属性窗口中修改账户密码,然后 ...

  7. iPhone屏幕尺寸、分辨率及适配

    转:http://blog.csdn.net/phunxm/article/details/42174937 目录(?)[+]   1.iPhone尺寸规格 设备 iPhone 宽 Width 高 H ...

  8. Swift - 实现点击cell动态修改高度

    Swift - 实现点击cell动态修改高度 效果 源码 https://github.com/YouXianMing/Swift-Animations // // TapCellAnimationC ...

  9. GOOGLE不能访问的解决方法

    1VPN gate 2自 由 门 3修改Windows\System32\drivers\etc hosts (复制https://github.com/txthinking/google-hosts ...

  10. XML 文档和数据

    .NET Framework 4.5 其他版本 .NET Framework 提供了一组全面而集成的类,可用来方便地生成可以识别 XML 的应用程序. 通过以下命名空间中的类,可以分析和编写 XML, ...