一、解决方法:
1. QT4版本
中文乱码解决办法是在main.cpp文件加入:
#include <QTextCodec>
int main(int argc, char **argv)
{
......
// 以下部分解决中文乱码
//TextCodec *codec = QTextCodec::codecForName("System"); //获取系统编码
QTextCodec *codec = QTextCodec::codecForName("utf8"); //Linux
QTextCodec::setCodecForTr(codec);
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
// 以上部分解决中文乱码
......
}
Windows 系统里一般的记事本、编辑器、VC++ 开发环境等都是默认用 GBK 汉字编码,而 Linux 和 Qt 都是默认用 UTF-8 国际文字编码,所以文本显示乱码一般都是这个原因。
2. QT5版本
Qt5版本之后,类QTextCodec
已经取消了QTextCodec::setCodecForTr()
和QTextCodec::setCodecForCString()
这两个函数
上述方法也不能解决中文乱码的问题了。需要用新方法。
第一种:
先将对应的cpp文件用记事本打开,另存为UTF-8格式,然后在代码中,遇到中文字符,使用QStringLiteral(“中文”)
进行修饰
第二种:
在头文件申明中加上
#pragma execution_character_set(“utf-8”)
二、QString 为什么会乱码呢
真的是 QString 乱码了吗?QString 采用的unicode编码,在中文支持上不存在任何问题。
“我是汉字” 是C语言中的字符串,它是char型的窄字符串。
const char * str = “我是汉字”;
QString a= str;
//或
char str[] = “我是汉字”;
QString a= str;
QString内部采用的是 Unicode,它可以同时存放:
1、GBK中的字符"我是汉字"
2、BIG5中的字符"扂岆犖趼"
3、Latin-1中的字符"ÎÒÊǺº×Ö"。
所以源代码中的这8个字节"\xce\xd2\xca\xc7\xba\xba\xd7\xd6",该怎么转换成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包起来,这有分两种:
(1) 用tr包住英文(最最推荐的用法,源码英文,然后提供英文到其他语言的翻译包)
(2) 用tr包住中文(源码用中文,然后提供中文到其他语言的翻译包)
注意:如果你正在用tr包裹中文字符,却不属于情况(2),那么你是在误用tr,你需要的是QString,而不是tr,
如果你确实属于(情况2),请做好心理准备,你可能还会遇到很多困难。
那么tr 是做什么的?下面二者的区别是什么?
QString text1 = QObject::tr(“hello”);
QString text2 = QString(“hello”);
tr是用来实现国际化,如果你为这个程序提供了中文翻译包(其中hello被翻译成中文"你好"),那么text1的内容将是中文"你好"。
tr是经过多级函数调用才实现了翻译操作,是有代价的,所以不该用的时候最好不要用。
你如果使用QObject::tr,你应该全部用英文表示,然后后面借助Linguist翻译成中文,就不会乱码了。
QObject::tr()在QObject的manual,QCoreApplication::translate()在QCoreApplication的manual中。
tr内内部调用的是translate。