记录一次QT乱码问题

本文讲述了在使用QT5开发过程中遇到的乱码问题,源于源文件UTF-8BOM和MSVC执行字符集冲突。作者提供了使用mingw编译器或在MSVC中设置预编译指令以解决编码问题的解决方案。
摘要由CSDN通过智能技术生成

问题描述

在敲陆文周的书《QT5开发及实例》的示例代码时,出现乱码,如下图所示
在这里插入图片描述
具体代码如下

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->treeWidget->clear();

    int groupSize = 2;
    int itemSize = 4;


    for(int i=1;i<=groupSize;i++){
        QTreeWidgetItem *group = new QTreeWidgetItem(ui->treeWidget);
        group->setText(0,QString("小组")+QString::number(i));
        group->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
        group->setCheckState(0,Qt::Unchecked);
        for(int j=1;j<=itemSize;j++){
            QTreeWidgetItem *subItem = new QTreeWidgetItem(group);
            subItem->setText(0,QString("项目")+QString::number(i)+QString::number(j));
            subItem->setFlags(Qt::ItemIsUserCheckable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
            subItem->setCheckState(0,Qt::Unchecked);
        }
    }
}

原因分析

在阅读csdn大佬急支糖浆的文章后,理解了 源文件码字符集,执行字符集等概念。

  • 源文件编码字符集:源文件保存时的编码方式,如gbk,utf-8等。
  • 执行字符集:编译器编译后的可执行文件的编码方式。
    本人采用的源文件编码字符集为UTF-8 BOM,编译器为msvc2019,由于源文件编码字符集带BOM,因此,msvc的执行字符集会变为local编码,即GBK(系统为中文系统)。到这里,一切都是正常的。
    罪魁祸首:因为QT中的QString在初始化时会使用QString::fromUTF8将UTF-8编码转为UTF-16编码,由于执行编码为gbk,这里使用fromUTF8是错误的,这便是乱码的原因所在,下图可证明我的观点:
    在这里插入图片描述
    可以看到,使用cout打印出字符串是正确的,因为它不需要像QString那样使用fromUTF8函数进行转码。

解决方案

  • 换成mingw编译器,这样无论源文件编码字符集是否带BOM,mingw都会采用utf8作为执行字符集,这样QString使用fromUTF8函数就能转码成功。
  • 继续使用msvc编译器,但需要加上预编译指令指示编译器采用utf-8作为执行字符集#pragma execution_character_set("utf-8")
  • 继续使用msvc编译器,但是将文件编码方式设置为不带BOM,这样fromUTF8也能正确转码,但可能出现其它问题,如一些中文的标点字符是必须带BOM的,会让编译器无法识别而报错,因此不推荐该方法。
    在这里插入图片描述
  • 指示QString使用locale编码来进行转码,但这种方式在高版本的qt中貌似已经失效
 QTextCodec *codec = QTextCodec::codecForName("utf-8");

 QTextCodec::setCodecForLocale(codec);
 QTextCodec::setCodecForCStrings(codec);
 QTextCodec::setCodecForTr(codec);

推荐采用第二种方案解决。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值