Qt报错: error: C2001: 常量中有换行符,解决QT运行时有中文乱码

Qt系列文章目录

前言

在编译别人的Qt工程中,总会遇到莫名其妙的问题,在别人机器上运行好好的工程,拷贝到自己机器上往往会报各种错误。首先代码是没有问题的,问题一般都处在Qt的版本不同、配置不同、中文编码格式的问题等等。特别是工程中含有中文字符的时候。
在这里插入图片描述
在这里插入图片描述

一、问题原因

在UTF-8中,一个汉字占3个字节(一个字符占一个字节)
BOM即byte order mark ,中文名译作“字节顺序标记”。在UCS 编码中有一个叫做 “Zero Width No-Break Space” ,中文译名作“零宽无间断间隔”的字符,它的编码是 FEFF。而 FEFF 在 UCS 中是不存在的字符,所以不应该出现在实际传输中。UCS 规范建议我们在传输字节流前,先传输字符 “Zero Width No-Break Space”。这样如果接收者收到 FEFF,就表明这个字节流是 Big-Endian 的;如果收到FFFE,就表明这个字节流是 Little- Endian 的。因此字符 “Zero Width No-Break Space” (“零宽无间断间隔”)又被称作 BOM。UTF-8 不需要 BOM 来表明字节顺序,但可以用 BOM 来表明编码方式。字符 “Zero Width No-Break Space” 的 UTF-8 编码是 EF BB BF。所以如果接收者收到以 EF BB BF 开头的字节流,就知道这是 UTF-8编码了。Windows 就是使用 BOM 来标记文本文件的编码方式。

UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。

二、解决办法

1.第一种方法:改变文件的编码格式

使用notepad++等文本编辑器打开.h/.cpp文件,
在这里插入图片描述
然后文件另存为即可。注意,这个方法有个问题,这种编码格式的转换是不可逆的,即 如果你之前的文件文本格式是ANSI编码,你现在转换成UTF-8,如果你再想把UTF-8转换成ANSI编码多半会发生错误。

2.第二种方法:修改代码

凡是有中文的地方前面一律加上"u8"

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

    //隐藏表头
    ui->treeWidget->setHeaderHidden(true);

    //打开右键菜单属性
    ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);

    //添加顶层节点
    QTreeWidgetItem *topItem1 = new QTreeWidgetItem(ui->treeWidget);
    topItem1->setText(0,u8"百度");
    ui->treeWidget->addTopLevelItem(topItem1);

    //右键菜单
    m_menu = new QMenu(ui->treeWidget);
    m_menu->addAction(u8"添加");
    m_menu->addAction(u8"删除");

    QTreeWidgetItem *item11 = new QTreeWidgetItem(topItem1);
    item11->setText(0,u8"研发部");
    //设置数据,可以带多种数据
    item11->setData(0,Qt::UserRole,100/*人员数量*/);
    item11->setData(0,Qt::UserRole+1,"李彦宏"/*负责人名字*/);

    //获得数据
    item11->data(0,Qt::UserRole).toInt();
    item11->data(0,Qt::UserRole+1).toString();

    QTreeWidgetItem *item12 = new QTreeWidgetItem(topItem1);
    item12->setText(0,u8"销售部");
    QTreeWidgetItem *item13 = new QTreeWidgetItem(topItem1);
    item13->setText(0,u8"人事部");

    QTreeWidgetItem *topItem2 = new QTreeWidgetItem(ui->treeWidget);
    topItem2->setText(0,u8"腾讯");
    topItem2->setCheckState(0,Qt::Checked);
    ui->treeWidget->addTopLevelItem(topItem2);

    QTreeWidgetItem *item21 = new QTreeWidgetItem(topItem2);
    item21->setText(0,u8"研发部");
    item21->setCheckState(0,Qt::Checked);
    QTreeWidgetItem *item22 = new QTreeWidgetItem(topItem2);
    item22->setText(0,u8"销售部");
    item22->setCheckState(0,Qt::Checked);
    QTreeWidgetItem *item23 = new QTreeWidgetItem(topItem2);
    item23->setText(0,u8"人事部");
    item23->setCheckState(0,Qt::Checked);

    //设置展开
    ui->treeWidget->expandAll();

    ui->treeWidget->setStyleSheet(styles);

    connect(ui->treeWidget,&QTreeWidget::itemClicked,this,
            &Form::slotClicked);

    connect(ui->treeWidget,&QTreeWidget::customContextMenuRequested,
            this,&Form::slotMenuPopup);

}

在这里插入图片描述

总结

感觉还是第二种办法好,适用性更强。

猜你喜欢

转载自blog.csdn.net/aoxuestudy/article/details/126617627