QT中文编码理解

QT中文编码学习

一、先来看一下编辑器设置编码格式有何作用

Ubuntu16.4 QT5.12环境下:
QT中文编码理解_第1张图片

编辑器编码为GBK,简单打印一句中英文,在嵌入式中运行,串口控制台编码也是GBK,结果却是乱码

在这里插入图片描述

接着尝试把编辑器编码改为UTF-8,重新构建,却并不会编译!即qmake视之未改变。

同时把xshell编码改成UTF-8,即可正常显示中文。

在这里插入图片描述

此时得出结论编辑器调整编码对程序打印中文没有影响。

二、接下来试验代码调整编码格式

QT里有一个类叫QTextCodec,打开其帮助可以看到
QT中文编码理解_第2张图片

  • 大概是说QTextCodec类提供了文本代码的相互转换,Qt使用统一码(Unicode)来储存,绘制(draw)和操作字符串。但是,很多情况下你可能会想用更多的编码方法来处理数据。例如大多数的日语文档都还在使用Shift-JIS或者2022-JP来储存,但是俄罗斯的用户就会用KOI8-R或者Window-1251来储存文档。然而Qt提供了这一套QTextCodec类来帮助不统一的编码转换成统一码。
  1. Qstring到QByteArray

QT设置编码的语句如下所示:

QTextCodec *GBK = QTextCodec::codecForName("GBK"); //设置编码格式为GBK
QTextCodec::setCodecForCStrings(GBK);  
QTextCodec::setCodecForTr(GBK); 
QTextCodec::setCodecForLocale(GBK);  //从QT5之后只剩这一句可用

QString str1("你好Hello");
QByteArray local = str1.toLocal8Bit();

其实Qt默认会使用本机编码,所以对于中文系统,第一句设置有时候是多余的(Windows下设置GBK是多余的,Linux下设置UTF-8是多余的)

  • 那么 setCodecForLocale有什么用呢?

​ 它用于设置本机编码格式,但要配合Qstring的toLocal8Bit()方法转换为QByteArray 类型,才能得到GBK编码的数据,如line6-7所示。

显然我们不止一种to开头的转换方法,实际上有这么多:

QT中文编码理解_第3张图片

不过这些也不全是转换字符串格式的方法,下面介绍另外两种格式转换方法:

	QByteArray local = str1.toLocal8Bit(); //受setCodecForLocale影响,强制转换为GBK编码
    printf("%s\n",local.data());
    QByteArray Latin1 = str1.toLatin1();  // 不受setCodecForLocale影响,强制转换为ISO-8859-1编码
    printf("%s\n",Latin1.data());
    QByteArray Utf8 = str1.toUtf8();       // 不受setCodecForLocale影响,强制转换为UTF-8编码
    printf("%s\n",Utf8.data());
    
UTF-8下输出:
	ţºello
	??Hello
	你好Hello
GBK下输出:
	你好Hello
	??Hello
	浣犲ソHello

可以看到格式真的转换了,于是Qstring到QByteArray的转换被我们打通了。

  1. QByteArray到Qstring

	QTextCodec *GBK = QTextCodec::codecForName("GBK"); //设置编码格式为GBK
    QTextCodec *UTF8 = QTextCodec::codecForName("utf-8");//设置编码格式为UTF-8
	QByteArray ba1 = "你好Hello";//此时还是UTF8
	/*局部编码转统一码Unicode*/
    QString str2 = GBK->toUnicode(local);//GBK编码的ByteArray强制转换为unicode编码的QString  注意local一定得是GBK编										    码,否则转换结果会出错
    printf("%s\n",str2.toStdString().data()); //这里的Unicode编码其实就是UTF-8  与QT编辑器相关
    QString str3 = UTF8->toUnicode(ba1);//  注意bal一定得是UTF-8编码
    printf("%s\n",str3.toStdString().data()); //Unicode编码
    /*统一编码转局部编码*/
    ba1 = GBK->fromUnicode(str2);//把Unicode转成GBK,这里的str2一定得是Unicode编码
    printf("%s\n",ba1.data());
    ba1 = UTF8->fromUnicode(str3);//str3同理
    printf("%s\n",ba1.data());
    
UTF-8下输出:
	你好Hello
	你好Hello
	ţºello
	你好Hello
GBK下输出:
	浣犲ソHello
	浣犲ソHello
	你好Hello
	浣犲ソHello

可以看到确实转换了,最终QByteArray到Qstring的转换也被我们打通了

  1. QByteArray与Qstring的区别

QString是专门用来处理字符串的,除了能处理ASCII编码字符,还包括各国语言的编码,默认情况下QString会把所有数据当做utf-8编码来处理。QByteArray只是单纯用来处理数据的,除了能处理ASCII编码字符,其它复杂的编码不能处理,直接以字节流的方式来对待。

    QString str("小马哥");
    QByteArray byte("小马哥");
    qDebug() << "str:" << str << "byte:" << byte << endl;
    printf("%s\n",byte.data());
    printf("%s\n",str.toStdString().data());
    
输出:
str: "小马哥" byte: "\xE5\xB0\x8F\xE9\xA9\xAC\xE5\x93\xA5" 

小马哥
小马哥

这里也描述了打印两种类型变量的方法。

  1. 转换过程的中间变量

    QByteArray temp1 = str1.toLocal8Bit();
    printf("%p\n",temp1.data());
    
    temp1 = str2.toLocal8Bit();
    printf("%p\n",temp1.data());
    
    temp1 = str3.toLocal8Bit();
    printf("%p\n",temp1.data());
    
    temp1 = str4.toLocal8Bit();
    printf("%p\n",temp1.data());
输出:
    0xbab1b0
    0xbab010
    0xbab1b0
    0xbab010

这里str1-4是四个不同的QString,我们把它们转换成GBK后打印地址(因为调用data方法返回char*类型的指针,且带有停止符)

QT中文编码理解_第4张图片

可以看到地址只有两种,如果稍作修改,不再共用一个QByteArray

    QByteArray temp1 = str1.toLocal8Bit();
    printf("%p\n",temp1.data());
    
    QByteArray temp2 = str2.toLocal8Bit();
    printf("%p\n",temp2.data());
    
    QByteArray temp3 = str3.toLocal8Bit();
    printf("%p\n",temp3.data());
    
    QByteArray temp4 = str4.toLocal8Bit();
    printf("%p\n",temp4.data());
输出:
	0x181a1a0
	0x181a000
	0x181a020
	0x181a040

可以看到不再共用一个地址,因此为了节省空间就要用前一种方法。

你可能感兴趣的:(qt5,linux,gbk,utf,嵌入式)