Qt | QTextCodec类使用详解、GBK和UTF8编码互转、QString的toLocal8bit和toLatin1区别
目录
- Qt | QTextCodec类使用详解、GBK和UTF8编码互转、QString的toLocal8bit和toLatin1区别
- 1、QTextCodec简介及使用
- 1.1 编码之间的转换
- 1.2 解决中文显示乱码问题
- 2、QString的toLocal8bit和toLatin1
1、QTextCodec简介及使用
1.1 编码之间的转换
Qt使用Unicode来存储、绘制和操作字符串。
unicode是各个编码格式转换的媒介,以UTF-8转到GBK格式为例,需要先将UTF-8转到UNICODE,在通过unicode转到GBK,反之亦然。
Qt提供了一组QTextCodec类,以帮助将非Unicode格式转换为Unicode格式。您还可以创建自己的编解码器类。
支持的编码包括:
- Big5
- Big5-HKSCS
- CP949
- EUC-JP
- EUC-KR
- GB18030
- HP-ROMAN8
- IBM 850
- IBM 866
- IBM 874
- ISO 2022-JP
- ISO 8859-1 to 10
- ISO 8859-13 to 16
- Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
- KOI8-R
- KOI8-U
- Macintosh
- Shift-JIS
- TIS-620
- TSCII
- UTF-8
- UTF-16
- UTF-16BE
- UTF-16LE
- UTF-32
- UTF-32BE
- UTF-32LE
- Windows-1250 to 1258
注:gb18030字符集兼容了gbk字符集,以两个字节表示一个文字。
现在假设有一组GBK格式的数据,需要转为unicode格式字符串,那么可以这样:
QByteArray encodedString = "...";
QTextCodec *codec = QTextCodec::codecForName("GBK");
QString string = codec->toUnicode(encodedString);
同样的,如果现在有一组unicode字符串需要转为GBK码数据,那么就是这样:
QString string = "...";
QTextCodec *codec = QTextCodec::codecForName("GBK");
QByteArray encodedString = codec->fromUnicode(string);
以上为简单的使用,还有一个经常遇到的问题就是Qt在windows和linux下中文显示乱码的问题。
1.2 解决中文显示乱码问题
很多新手直接网上一查就是下面三句解决中文乱码问题:
QTextCodec* codec = QTextCodec::codecForName("GBK");
// 或者QTextCodec* codec = QTextCodec::codecForName("gb18030 或 gbk 或 utf8");
QTextCodec::setCodecForCStrings(codec); // 在qt5中不存在
QTextCodec::setCodecForTr(codec); // 在qt5中不存在
QTextCodec::setCodecForLocale(codec);
这三个函数的作用如下:
setCodecForCStrings(codec):设置QString用于转换const char*和QByteArrays的编解码器。如果编解码器为0(默认值),QString将采用Latin-1。
setCodecForTr(codec):设置QObject::tr()的编码器。如果codec为0(默认值),tr()将采用Latin-1。
setCodecForLocale(codec):将本地编解码器设置为codec,可以由codecForLocale函数返回。如果c是空指针,则编解码器将重置为默认值。对于一些希望使用自己的机制来设置区域设置的应用程序来说,这个功能会有用。
加上这三句后发现真的解决了中文乱码问题!!(固定系统、固定地区语言设置、固定编译环境)。
但是这么干是不对滴!可能换了个系统还是出问题!
那么这三句到底有何作用?下面就详细说一下。
// 获取编解码器名称
qDebug() << QTextCodec::codecForLocale()->name(); // windows下打印GBK,linux下打印utf8
在编写Qt代码的时候使用中文字符串的时候一般会有这三种形式,分别为const char*
这种C格式的字符串、QString()进行构造的形式、tr()进行构造的形式:
QString s1 = "你好"; // 形式1
QString s2("你好"); // 形式2
QString s3 = tr("你好"); // 形式3
setCodecForCStrings就是设置的形式一和形式二所用的编码器。
setCodecForTr就是设置使用tr()函数时的所用的编码器。
在Qt4中,如果你没有使用setCodecForCStrings和setCodecForTr指定编解码的方式,那么就会采用Latin-1格式,也就是ASCII。
此时将<你好>这两个中文汉字传入QString,这两个汉字不存在于Latin-1字符集里,自然是会乱码显示,这就是原因!
到了Qt5中,就把setCodecForCStrings和setCodecForTr给去掉了,并将QString()的构造函数默认调用的是fromUTF8,且Qt Creator的文件编码格式默认为UTF-8。
可以从这里看:工具->选项->文本编辑器
而对于使用VS的用户来说,默认编码或者你设置的编码可能是不是UTF8,所以出现了中文显示乱码的问题!这就是Qt5下中文显示乱码的原因!
2、QString的toLocal8bit和toLatin1
QString的toLocal8bit和toLatin1都可以将QString转化为QByteArray,但是两者的区别在于编码的不同。
-
toLocal8Bit:转为本地8bit编码格式。如果字符串包含本地8位编码不支持的字符,则返回的字节数组未定义。前面说过Qt使用Unicode来存储、绘制和操作字符串,执行。执行toLocal8Bit就相当于将unicode编码的qstring转为了本地编码格式,对于windows系统,本地编码格式为GBK,linux系统为UTF-8。
-
toLatin1:以QByteArray的形式返回字符串的Latin-1表示形式。也就是转为了ASCII编码。如果字符串包含非Latin1字符,则返回的字节数组未定义。这些字符可以被抑制或替换为问号。
下面进行示例演示。
QString s = "你好";
qDebug() << s.size(); // 输出2(qt用unicode编码格式组织QString)
qDebug() << s;
qDebug() << s.toUtf8().size(); // 输出6(UTF8用三个字符表示一个汉字)
qDebug() << s.toUtf8(); // 转utf8
qDebug() << s.toLocal8Bit().size(); // 输出4(window下默认编码格式为GBK,一个GBK汉字占两个字节)
qDebug() << s.toLocal8Bit(); // 转本地编码,也就是GBK格式
qDebug() << s.toLatin1().size(); // 输出2
qDebug() << s.toLatin1(); // 转ASCII格式,由于汉字不存在于ASCII编码中,所以会输出两个问号
程序运行结果:
ends…