关闭

QT文本编码

标签: qtpluginscodectransformation语言扩展
622人阅读 评论(0) 收藏 举报
分类:

字符集简史

  在所有字符集中,最知名的可能要数被称为ASCII的7位字符集了。它是美国信息交换标准代码(American Standard Code for Information Interchange)的缩写, 为美国英语通信所设计。它由128个字符组成,包括大小写字母、数字0-9、标点符号、非打印字符(换行符、制表符等4个)以及控制字符(退格、响铃等)组成。

  但是,由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题。因此,创建出了一些包括255个字符的由ASCII扩展的字符集。其中有一种通常被称为IBM字符集,它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。另一种8位字符集是ISO 8859-1 Latin 1,也简称为ISO Latin-1。它把位于128-255之间的字符用于拉丁字母表中特殊语言字符的编码,也因此而得名。

 

 

 

 

 

 

 

 

 

 

 

 

欧洲语言不是地球上的唯一语言,因此亚洲和非洲语言并不能被8位字符集所支持。仅汉语(或pictograms)字母表就有80000以上个字符。但是把汉语、日语和越南语的一些相似的字符结合起来,在不同的语言里,使不同的字符代表不同的字,这样只用2个字节就可以编码地球上几乎所有地区的文字。因此,创建了UNICODE编码。它通过增加一个高字节对ISO Latin-1字符集进行扩展,当这些高字节位为0时,低字节就是ISO Latin-1字符。UNICODE支持欧洲、非洲、中东、亚洲(包括统一标准的东亚象形汉字和韩国象形文字)。但是,UNICODE并没有提供对诸如Braille, Cherokee, Ethiopic, Khmer, Mongolian, Hmong, Tai Lu, Tai Mau文字的支持。同时它也不支持如Ahom, Akkadian, Aramaic, Babylonian Cuneiform, Balti, Brahmi, Etruscan, Hittite, Javanese, Numidian, Old Persian Cuneiform, Syrian之类的古老文字。

  事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-7.5, UTF-8, UTF-16, 以及 UTF-32。本文讨论UTF-8字符集的基础。

 

 

QT中的QString内容使用Unicode作为文本编码。但是实际系统中通常采用的是其他编码,例如GBK,utf8等。为了便于兼容这些格式,QT中还设置了两个字符串类型:

QCString类: C类型字符串,必须以0结尾,也就是中间不能含有0. 例如GBK编码的字符串

QByteArray类: 中间可以含有0.例如utf8编码的字符串

 

为了便于编码转换,QT还提供了一套具备扩展性的编码转换器:

QTextCodec

这个类定义了编码转换器的接口,可以以插件方式继承这个类,实现各种编码转换器。

当然,QT也内置了多种编码转换器(不包括GBK)。

在使用编码转换器时,有以下几种方式:

 

1. 在程序开始位置设置QObject的成员函数tr()的编码器,后面程序中都可以用tr()直接转换字符串;

QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); //或者codecForName("GBK")

… ….

QString str(tr(“本地文本”));

2. 用QTextCodec的toUnicode方法来显示中文

QTextCodec *codec = QTextCodec::codecForLocale();

QString a = codec->toUnicode("本地文本");

3. 使用QString的fromLocal8Bit()函数族;

QString str = str.fromLocal8Bit("哈哈哈");

 

通过比较,方法1对于界面文本处理是比较好的,可以一次设置,全局使用。而且tr函数可以用于国际化,在把软件转换为其他语言版本或者多语言版本时,只需通过qm文件就可以,非常方便。

方法2使用非常灵活,适合于程序中处理特定编码字符串的时候使用. 例如读取文件内容。

方法3只是为了方便QString类使用,而对QTextCodec类的toUnicode()函数进行的一些封装。效率上肯定要差一些。例如:fromLocal8Bit()就是利用了codeForLocale()解码器。

 

可能遇到的问题:

调用QTextCodec::codecForLocale();没有问题。

而调用plugins中的codecs,例如GBK. QTextCodec:: codecForName("GBK")就找不到相应的解码器,得到空指针。

这种情况通常是你的QT编译时是作为静态链接库形式编译的。而plugins需要是动态链接库。要先检查你用到的plugins是否已经编译了,插件都放在qtXXX/plugins/文件夹下了。例如GBK,GB18030,GB2312的解码器的调试版本就是qtXXX/plugins/codecs/qcncodecsd4.dll。

 

    //app.addLibraryPath(QObject::tr("C://qt-win-opensource-src-4.4.3//plugins")); //这段代码不用加入也可以正常执行,如果加入的话,路径中最好不要有中文

    QTextCodec *codec = QTextCodec::codecForName("GBK");

QString teststr = codec->toUnicode("GB编码");

 

 

此外,为了对某些分块的字符串(例如从网络中获得的字符串片段)进行编码转换,QT还提供了一个QTextDecoder的辅助类,可以帮助对这类字符串进行解码。

QTextCodec *codec = QTextCodec::codecForName("Shift-JIS");

QTextDecoder *decoder = codec->makeDecoder();

 

QString string;

while (new_data_available()) {

     QByteArray chunk = get_new_data();

     string += decoder->toUnicode(chunk);

}

0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:175766次
    • 积分:2230
    • 等级:
    • 排名:第16842名
    • 原创:51篇
    • 转载:5篇
    • 译文:4篇
    • 评论:23条
    博客专栏
    文章分类
    最新评论