QT的中文显示乱码问题解决

9 篇文章 3 订阅

QT的中文显示乱码问题解决:

1、查看源文件的编码格式,有必要的话转换源文件的编码格式再重新编译运行尝试汉字能否正常显示。

1、编码格式不对:明明加了头文件跟写了声明,但是VS还会报错:
			写代码没有代码提示。
			常量中有换行符。
			未定义的标识符。
			还有一些其他的莫名其妙的问题。
			
2、转换报错源文件编码格式:

	1、比如VS新建的源文件或者你当前报错的源文件的编码格式是这里面其中之一:”UTF-8“、”UTF-8-BOM“、"ANSI"、”UCS-2 Big Endian“、"UCS-2 Little Endian""UTF-16 LE""UTF-16 BE"2、用Windows记事本或者Notpad++或者Linux的gedit打开报错的源文件,查看报错源文件当前编码格式,比如,报错源文件的编码格式是”UTF-8“。
	
	3、然后再用Windows记事本或者Notpad++或者Linux的gedit打开项目中正常没有报错的源文件,比如,项目中正常的源文件编码格式是”UTF-8-BOM“。
	
	4、用Notpad++打开报错源文件,在工具栏的“编码”一栏可以选择“转为“UTF-8-BOM”编码”,然后记得保存修改。重新编译链接生成问题应该就解决了。
		
		或者:
		用Windows的记事本打开源文件,在菜单栏文件里面选择“另存为”,然后在打开的窗口里可以选择编码为“UTF-8-BOM”,然后记得保存修改。重新编译链接生成问题应该就解决了。

2、在代码里面解决:

2、qDebug() << QStringLiteral("录屏完成"));			推荐
	
3、qDebug() << QObject::tr("1中文"));				推荐国际化软件使用,其余不推荐

4、qDebug() << QString::fromLocal8Bit("4中文");		不推荐,

5、qDebug() << QString::fromLatin1("3中文");			不推荐

6、qDebug() << QString::fromUtf8("5中文");			推荐

7、qDebug() << QString::fromWCharArray(L"6中文");	不推荐,字符串的编码取决于 wchar 的大小。

8、qDebug() << QStringLiteral("hello word %1");		不推荐,

9、qDebug() << (u8"显示轨迹关键点");			//在中文字符前加上 u8,然后把中文字符用双引号包括			推荐

10、在头文件的类前面放入这一行,设置源文件的编码格式:	
# pragma execution_character_set("utf-8")

3、用法:

当QTextCodec::codecForName("utf-8");时,QString::fromLocal8Bit和QString::fromUtf8是等效的。

当QTextCodec::codecForName("gbk");时,QString::fromLocal8Bit和QString::fromUtf8是不等效的。


1、QStringLiteral("录屏完成")		推荐
	使用QStringLiteral宏可以在编译期把代码里的常量字符串“str”直接构造为QString对象,于是运行时就不再需要额外的构造开销了。

	如果编译器支持,则 QStringLiteral 宏在编译时从 str 生成一个 QString 的数据。在这种情况下从 QStringLiteral 创建一个 QString 是自由的,生成的字符串数据存储在编译的目标文件的只读段中。

	对于不支持创建编译时字符串的编译器,QStringLiteral 的使用效果将与使用 QString::fromUtf8() 一样。


2、QObject::tr("1中文")				推荐国际化软件使用,其余不推荐
	 
	tr()是QT的基类QObject 的方法,所有QObject的子类都可以继承该方法。
	tr()全名是QObject::tr(),被它处理的 字符串可以 使用工具提 取出来翻译 成其他语言, 也就是做国际化使用。
	
	Qt 的最佳实践:如果你想要你做的程序国际化,那么,就把所有用户可见的字符串都要使用 QObject::tr()!可直接用工具翻译成多语言的版本。

	tr 是做什么的?下面二者的区别是什么?

		QString text1 = QObject::tr("hello");
		QString text2 = QString("hello");

	tr是用来实现国际化,如果你为这个程序提供了中文翻译包(其中hello被翻译成中文"你好"),那么text1的内容将是中文"你好";
		如果你为程序提供且使用日文翻译包,那么text1的内容将是“こんにちは”。

	tr是经过多级函数调用才实现了翻译操作,是有代价的,所以不该用的时候最好不要用。

	总结
		如果没有国际化需求的情况下是没必要去使用tr的,直接使用QString省去了多级函数的调用,提高效率它不香吗(●’◡’●)3、QString::fromLocal8Bit("4中文")		(不推荐)

	qt fromLocal8Bit()函数可以设置编码。

	QT默认的编码是unicode,不能显示中文的。
	
	windows默认使用(GBK/GB2312/GB18030)

	使用fromLocal8Bit()函数,实现了从本地字符集GB到Unicode的转换,用于处理汉语显示乱码等问题。

	static inline QString fromLocal8Bit(const QByteArray &str);该函数返回的是String类型的数
	
	不推荐,	不是每次都能凑效的。因为这个Local是可以动态变化的。再啰嗦一次,如果是中文操作系统,这个local就是gbk,恰好不换操作系统环境,恰好写中文恰好可以显示。但是如果换个操作系统,比如用户运行环境是英文操作系统;或者编程中动态使用上面的SetCodecForLocale修改了编码,则下面的FromLocal8Bit处理中文就又稀里糊涂的会出现乱码。


4、QString::fromLatin1("3中文")				不推荐
	
	将 Latin-1 字符 c 转换为其等效的 QChar。 这主要对非国际化软件有用。
	
	
5、QString::fromUtf8("5中文")				推荐,保证源输入文件是utf8编码的,编程处理也简化直接按照utf8来读取。
	
	返回使用 UTF-8 字符串 str 的第一个 size 字节初始化的 QString。
	如果 size 为 -1(默认值),则采用 strlen(str)。

	UTF-8 是一种 Unicode 编解码器,可以表示 Unicode 字符串(如 QString)中的所有字符。但是,UTF-8 可能会出现无效序列,如果发现任何此类,它们将被替换为一个或多个“替换字符”,或被禁止。这些包括非 Unicode 序列、非字符、超长序列或编码为 UTF-8 的代理代码点。

	只要所有UTF-8字符在传入数据中终止,此函数就可用于增量处理传入数据。字符串末尾的任何未终止字符都将被替换或抑制。为了进行有状态解码,请使用 QTextDecoder。

	返回使用 UTF-8 字符串 str 初始化的 QString。
	
	当然str中的中文需要使用u8来标识前缀的,或者本身就是读取文件中的utf8格式的字符串。
	这样保证源输入文件是utf8编码的,编程处理也简化直接按照utf8来读取。

6、QString::fromWCharArray(L"6中文")、			不推荐

	返回字符串的副本,其中字符串的编码取决于 wchar 的大小。 
	
	如果 wchar 为 4 字节,则字符串被解释为 UCS-4,
	
	如果 wchar 为 2 字节,则字符串被解释为 UTF-16。

	如果 size 为 -1(默认),则字符串必须以 0 结尾。


7(u8"显示轨迹关键点");	//在中文字符前加上 u8,然后把中文字符用双引号包括		推荐·
	
	凡是有中文的字符串,前面加前缀u8。这样就是显示告诉编译器,在生成exe文件字节码的时候,把中文编码为utf8格式,不要使用gbk或者其它编码。

	所以为了避免一些鬼畜的问题。我们如果保证文件保存一律使用utf8-bom编码格式保存,再保证条件编码中有中文则加前缀u8。就解决了所有这些鬼畜问题。代码中编程读取文件解析的时候,同样全部使用utf8格式来解析。这样就万无一失了。

	(3)QT中出现中文乱码的情况

		注意QT的本地编码,是可以在程序中动态变化的。

		QTextCodec *QTextCodec::codecForLocale() 
		这个函数可以获取当前QT运行环境中,使用的本地编码。不出意外的话,如果是中文操作系统,没有修改本地编码的情况下,这个返回就是GBK。

		void QTextCodec::setCodecForLocale(QTextCodec *c),可以编程动态去修改QT运行环境中的本地编码。

		许多QT使用者喜欢不分青红皂白直接调用QString QString::fromLocal8Bit来处理中文,这样不是每次都能凑效的。因为这个Local是可以动态变化的。再啰嗦一次,如果是中文操作系统,这个local就是gbk,恰好不换操作系统环境,恰好写中文恰好可以显示。
		但是如果换个操作系统,比如用户运行环境是英文操作系统;或者编程中动态使用上面的SetCodecForLocale修改了编码,则下面的FromLocal8Bit处理中文就又稀里糊涂的会出现乱码。

		我们压根就不应该随意使用QString QString::fromLocal8Bit,不要依赖本地编码,本地编码在不同系统上而不同。
		如果我们保证了前面说的条件(1)和条件(2):
		
			我们完全可以只使用如下这个接口:QString fromUtf8(const char *str, int size = -1) 。
			当然str中的中文需要使用u8来标识前缀的,或者本身就是读取文件中的utf8格式的字符串。代码中只按照utf8格式去解析处理字符串就行。即保证输入文件是utf8格式,编程也按照utf8来解析,则一切复杂问题都可以简化,甚至没有问题了。
			
		直接使用前面的QString fromUtf8(const char *str, int size = -1)。
		这样保证源输入文件是utf8编码的,编程处理也简化直接按照utf8来读取。
		大家都简单省事,省去了鬼畜的动态识别编码。
		动态识别本地编码,然后识别后匹配去解析文件,
		一句话,吃力不讨好,还可能出错。

	(4)u8能不能支持,是取决于编译器版本。
		在C++11之前,通常是使用L""来指定宽字符串,但是并没有要求编译器规定宽字符串的存储,对此windows使用的是2个字节,即UCS-2(早期),UTF-16(最新)。

		C++11引入了u8"utf-8字符串",u"utf-16字符串",U"utf-32字符串"。以及R"(非转义字符串)"可直接写不用转义的字符串,和对应的utf版本u8R"(utf-8非转义字符串)",uR"(utf-16非转义字符串)",UR"(utf-32字符串)"。

	简而言之,只要你编译器支持C++11,就是可以支持的了。目前大部分主流编译器都是支持的。


8、QStringLiteral("hello word %1")		不推荐·,参数需要QStirng参数类型的地方,再用。

	函数只能接受QString类型的参数时,无论我们给一个字面字符串或QLatin1String,都会隐式构造一个临时的QString对象,构造这个对象需要在栈上申请一定的内存空间,然后把字符串拷贝过去,如果这样的调用比较多,那还是一笔不小的开销。
	
	此时,我们可以使用QStringLiteral来减小这个开销。

	QStringLiteral其实是一个宏,从字符串常量创建QString对象的宏。

	宏在编译时,从字符串文字生成QString数据,QString的内部数据将在编译时生成,在运行时不会发生任何转换或内存分配,使用QStringLiteral来代替C++中的双重数值传递将会在编译的时候显著的提升运行效率。

**优点:**
	使用QStringLiteral而不是双引号的普通C++的字符串可显著加快从编译时已知的数据创建QString示例的速度,相对来说有QLatin1String参数重载的比使用QStringLieral更高效。

总结:

	参数能使用const char*类型或QLatin1String类型的地方使用相应的参数。
	参数需要QStirng参数类型的地方,若值不被修改,则使用QStirngLiteral宏。
	参数需要QString类型且QStirng可能被修改,则直接使用QString或隐式转换。
  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值