概述
一、解决方法
1. 之前QT4版本中文乱码解决办法是在main.cpp文件加入:
#include <QTextCodec>
int main(int argc, char **argv)
{
......
// 以下部分解决中文乱码
QTextCodec *codec = QTextCodec::codecForName("utf8"); //Linux
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
// 以上部分解决中文乱码
......
}
Windows 系统里一般的记事本、编辑器、VC++ 开发环境等都是默认用 GBK 汉字编码,而 Linux 和 Qt 都是默认用 UTF-8 国际文字编码,所以文本显示乱码一般都是这个原因
2. QT5版本之后,类QTextCodec已经取消了QTextCodec::setCodecForTr()和QTextCodec::setCodecForCString()这两个函数
上述方法也不能解决中文乱码的问题了。需要用新方法。
第一种:
先将对应的cpp文件用记事本打开,另存为UTF-8格式,然后在代码中,遇到中文字符,使用QStringLiteral(“中文”)进行修饰
第二种:
在头文件申明中加上
#pragma execution_character_set(“utf-8”)
二、QString 为什么会乱码呢
真的是 QString 乱码了吗?QString 采用的unicode,在中文支持上不存在任何问题
我们可以问问自己,我们抱怨的对象是不是搞错了?
继续之前,先明确几个概念:
明确概念0:
“我是汉字” 是C语言中的字符串,它是char型的窄字符串。
const char * str = “我是汉字”;
QString a= str;
或
char str[] = “我是汉字”;
QString a= str;
明确概念1:
源文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码,这个是问题的根源
明确概念2:
QString 内部采用的是Unicode。
QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"ÎÒÊǺº×Ö"。
一个问题是,源代码中的这8个字节"xcexd2xcaxc7xbaxbaxd7xd6",该怎么转换成Unicode并存到 QString 内?按照GBK、BIG5、Latin-1还是其他方式…
在你不告诉它的情况下,它默认选择了Latin-1,于是8个字符"ÎÒÊǺº×Ö"的unicode码被存进了QString中。最终,8个Latin字符出现在你期盼看到4中文字符的地方,所谓的乱码出现了
QString 工作方式
const char * str = “我是汉字”;
QString a= str;
其实很简单的一个问题,当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1
理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么:
就像下面的函数一样,QString的成员函数知道按照何种编码来处理 C 字符串
QString QString::fromAscii ( const char * str, int size = -1 )
QString QString::fromLatin1 ( const char * str, int size = -1 )
QString QString::fromLocal8Bit ( const char * str, int size = -1 )
QString QString::fromUtf8 ( const char * str, int size = -1 )
另外还有一种防止乱码的方法,此种方法也可以解决国际化问题导致的乱码,就是使用翻译文件。在源码中统一使用英文。在翻译文件中实现不同版本的语言。
不得不提最后一种比较高级的方法:QStringLiteral宏它可以直接生成Unicode字符串保存在可执行文件中的只读区域。这样运行时不会发生任何转换。可以显著提高程序运行效率。
但是QStringLiteral需要编译器支持,如支持C++11就具有这种特性。Qt高版本一般也支持。具体性能方面的影响请看Qt的帮助文档。
三、tr的误用
用tr的有两类人:
(1)因为发现中文老出问题,然后搜索,发现很多人用tr,于是他也开始用tr
(2)另一类人,确实是出于国际化的需要,将需要在界面上显示的文件都用tr包起来,这有分两种:
(2a) 用tr包住英文(最最推荐的用法,源码英文,然后提供英文到其他语言的翻译包)
(2b) 用tr包住中文(源码用中文,然后提供中文到其他语言的翻译包)
注意哦,如果你正在用tr包裹中文字符,却不属于(2b),那么,这是个信号:
你在误用tr,你需要的是QString,而不是tr
如果你确实属于(2b),请做好心理准备,你可能还会遇到很多困难,
tr 是做什么的?下面二者的区别是什么?
QString text1 = QObject::tr(“hello”); QString text2 = QString(“hello”);
tr是用来实现国际化,如果你为这个程序提供了中文翻译包(其中hello被翻译成中文"你好"),那么text1的内容将是中文"你好";如果你为程序提供且使用日文翻译包,那么text1的内容将是日文。
tr是经过多级函数调用才实现了翻译操作,是有代价的,所以不该用的时候最好不要用。
你如果使用QObject::tr,你应该全部用英文表示,然后后面借助Linguist翻译成中文,就不会乱码了。
QObject::tr()在QObject的manual,QCoreApplication::translate()在QCoreApplication的manual中。
tr内内部调用的是translate。
参考文档
https://blog.csdn.net/yueye30121/article/details/16114713
https://www.cnblogs.com/lsgxeva/p/7804631.html
最后
以上就是超帅爆米花为你收集整理的Qt乱码问题的全部内容,希望文章能够帮你解决Qt乱码问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复