Qt中文乱码解决办法

一、解决方法:

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。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值