Qt中关于中文显示乱码

本篇参考:

  1. 彻底弄懂Qt的编码
  2. QTextCodec中的setCodecForTr等终于消失了 (Qt5)

之前由于是在linux中使用中文,所以并没有出现中文乱码问题,但是最近在windows中,就出现中文乱码问题

在VS2015中新建工程,并在main.cpp中增加以下代码

1
2
3
4
5
6
7
8
9
10
11
#include <QDebug>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QString test("测试");
qDebug() << test;
return a.exec();
}

编译后会发现终端显示的是乱码。

分析

通过Notepad++打开文件可发现,此时文件的编码是ANSI,即本地编码,编译后打开exe文件也可以发现编码是ANSI

所以,Qt程序在生成可执行文件的过程中,会把字符串转换成本地编码

那又和乱码有什么关系呢?

原因是Qt内部使用的是Unicode编码,即QString保存的是Unicode编码的字符串

所以当可执行程序运行时,它再读取“测试“两个字的时候,它将本来是ANSI本地编码的字符串当做Unicode编码。所以就显示了乱码。

所以,解决乱码的根本是设置程序的编码为ANSI或者将ANSI编码转换为Unicode编码

设置程序的编码为ANSI

如果遇到乱码问题而在网上查询过解决办法的基本会看过下面这段代码

1
2
3
4
QTextCodec *codec = QTextCodec::codecForName("GBK");
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);

这种方法的原理主要是在编码转换过程中,说明字符串使用的是GBK编码,这样Qt就会将字符串从GBK转换为Unicode(不需要你进行转换,自动转换)。这样在程序运行就可以显示中文而不出现乱码

但是,这种方法已经在Qt5中被废弃了!!!

那去掉后,该怎么显式的告诉程序用的是什么编码?Qt使用的策略是只要你代码文件是utf-8编码,则编译过程中也是用utf-8编码,不会再出现ANSI编码问题

LinuxMacOS中的文件默认都使用utf-8编码,所以不需要设置什么。

Windows中则需要设置VS来使用utf-8,在项目属性 >> C/C++ >>命令行的其他选项中,增加/utf-8,并且需要注意的是,不要使用VS新建文件,需要自己手动新建utf-8格式文件,再用VS加入项目中

将ANSI编码转换为Unicode编码

还有比较简单的方式则是在代码中将字符串修改为Unicode编码

如图两种修改方式

1
2
3
4
// QString test("测试");
QString test(QString::fromLocal8Bit("测试");
QString test(QStringLiteral("测试"));

QString::fromLocal8Bit表示从本地的编码转换成Unicode编码再使用

QStringLiteral则是宏定义,它可以直接生成Unicode字符串保存在可执行文件中