使用Qt的时候,时常会遇到中文乱码问题,qDebug打印日志乱码,或者Widget界面乱码等等。
原因呢,大多是因为使用MSVC编译器问题导致,而Qt 自带的MinGW一般不会出现乱码问题。
核心原因呢,是因为编码问题,即UTF-8和GBK编码千古疑难问题
在 Qt Creator 中使用 MSVC 编译器编译项目时,若处理不当容易出现中文字符串乱码问题。
例如,程序运行时,LabInfo显示的汉字就会出现乱码。
void MainWindow::Changed()
{
QString str="测试";
ui->LabInfo->setText(str);
}
这是因为Qt Creator保存的文件使用的是UTF-8编码(是任何平台、任何语言都可以使用的跨平台的字符集),MSVC编译器虽然可以正常编译带BOM的UTF-8编码的源文件,但是生成的可执行文件的编码是 Windows 本地字符集,比如 GBK2312。
也就是在可执行文件中,字符串“测试”
是以GBK2312编码的,而可执行程序执行到这条语句时,对这个字符串却是以UTF-8解码的,这样就会出现乱码。
解决这个问题有两种方法
一种方法是使用 QStringLiteral()
宏或者QString::fromLocal8Bit()
封装字符串,另一种方法是强制 MSVC 编译器生成的可执行文件使用UTF-8编码。
QStringLiteral(str)宏在编译时将一个字符串 str 生成字符串数据,并且存储在编译后文件的只读数据段中,程序运行时使用到此字符串时,只需读出此字符串数据即可。
所以程序中需要使用QStringLiteral()宏对每个中文字符串进行封装,代码可改为:
QString str = QStringLiteral("测试");
缺陷:
需要对每个含有中文的字符串进行封装,而且tr()函数无法使用(无国际化翻译需求可忽略)
强制 MSVC 编译器采用 UTF-8 编码生成可执行文件,需要在每个使用到中文字符串的头文件和源程序文件的前部加入如下的语句:
#if _MSC_VER >= 1600 //VS2015>VS>VS2010, MSVC VER= 10.0 -14.0
#pragma execution_character_set("utf-8")
#endif
VS 2010-VS 2015 Update2的编译器可以使用此方案,这是强制编译后的执行文件采用UTF-8编码。这样,即使不再使用QStringLiteral()宏,程序运行时也不会再出现汉字乱码的问题了。而且,也可以采用tr()函数用于翻译字符串。
个人认为最优方案:
在pro文件中添加
msvc{
QMAKE_CFLAGS += /utf-8
QMAKE_CXXFLAGS += /utf-8
}
或者
msvc{
QMAKE_CXXFLAGS += /source-charset:utf-8 /execution-charset:utf-8
}
execution-charest表示执行字符集。source-charset表示源码字符集
两种方式都可以
注意:msvc
必须是小写,亲测大写MSVC
无效。另外,运行之前,建议清除一下,重新构建,删除之前的缓存。
一般而言,不会乱码,因为文本,编译器都是GBK编码。但是为了更好的跨平台兼容性,改为UTF-8编码的话,就需要做一些改动了。
/utf-8
测试发现,使用VS2019,用纯Qt方案二的_MSC_VER宏也可以解决乱码问题。
参考链接
/utf-8
execution_character_set