我是靠谱客的博主 超帅爆米花,最近开发中收集的这篇文章主要介绍Qt乱码问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、解决方法

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乱码问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部