windows下使用Qt Creator开发调试的注意事项

windows下的Qt项目弹出内置控制台Terminal进行程序输出查看调试,而不是在Qt Creator的Application Output窗口行程序输出查看调试

1.win32: CONFIG += console

2.点击 项目 → 运行

检查是否勾选 "在终端中运行"(Run in terminal)

对于 Windows,需要:Run in terminal

3.一定要重新编译,否则不生效

上述1或2任意一个没有设置,都不会弹出电脑内置的控制台程序,如下图所示,程序输出仍在Qt Creator的Application Output窗口,而Terminal窗口没有任何输出

如果严格按照上述1,2,3都设置了,那么程序输出讲出现在Terminal窗口,不再在Qt Creator的Application Output窗口出现,如下图所示:

为什么要弹出内置控制台Terminal进行程序输出查看调试,而不是在Qt Creator的Application Output窗口行程序输出查看调试呢?

因为要解决输出中文时的乱码问题,下面这条命令可以在windows下设置内置控制台Terminal的代码页,比如GBK(936)或者UTF8(65001);而Qt Creator的Application Output窗口没有很好的办法设置代码页,解决不了中文乱码问题

#ifdef Q_OS_WIN

SetConsoleOutputCP(CP_UTF8);

SetConsoleCP(CP_UTF8);

#endif

测试代码如下:

cpp 复制代码
void checkEnvironment() {
    qDebug() << "源代码编码测试:";

    // 测试字符"中"的不同编码
    // UTF-8: E4 B8 AD
    // GBK: D6 D0
    qDebug() << "'中'的原始字节:" << QByteArray("中").toHex();

    // 如果输出E4B8AD,说明是UTF-8
    // 如果输出D6D0,说明是GBK
}

int main(int argc, char *argv[])
{
    checkEnvironment();

        qDebug("11111测试qDebug(这里是参数)11111");
        qDebug() << "22222测试qDebug()<<字符串字面量22222 ";
        qDebug() << QStringLiteral("33333测试qDebug()<<QStringLiteral()33333");
        qDebug() << QString("44444测试qDebug()<<QString()44444");
        qDebug() << QString("55555测试qDebug()<<QString().toUtf8().constData()55555").toUtf8().constData();
        qDebug() << QString("66666测试qDebug()<<QString().toLocal8Bit().constData()66666").toLocal8Bit().constData();

        std::cout <<std::endl;

        std::cout << QString("测试std::cout << QString().toStdString() 哈哈哈哈: ").toStdString() << std::endl;
        std::cout << QString("测试std::cout << QString().toUtf8().constData() 哈哈哈哈: ").toUtf8().constData() << std::endl;
        //在SetConsoleOutputCP(CP_UTF8)设置后,下面这条语句因为字符编码问题直接不能打印输出,也相应的影响到了下面本来可以正常输出的语句,因此测试时
        //在SetConsoleOutputCP(CP_UTF8)设置后可以将此语句先注释掉,取消SetConsoleOutputCP(CP_UTF8)设置后再将此条语句取消注释
        std::cout << QString("测试std::cout << QString().toLocal8Bit().constData() 哈哈哈哈: ").toLocal8Bit().constData() << std::endl;
        std::cout << "测试std::cout << 字符串字面量 哈哈哈哈: " << std::endl;

        std::cout <<std::endl;

        printf(QString("测试printf QString().toUtf8().constData(): 哈哈哈哈哈哈哈哈\n").toUtf8().constData());
        //在SetConsoleOutputCP(CP_UTF8)设置后,下面这条语句因为字符编码问题不能打印输出汉字
        //取消SetConsoleOutputCP(CP_UTF8)设置后,下面这条语句可以打印输出汉字
        printf(QString("测试printf QString().toLocal8Bit().constData(): 哈哈哈哈哈哈哈哈\n").toLocal8Bit().constData());
        printf("测试printf 字符串字面:\n");
        fflush(stdout);

        std::cout <<std::endl;
}

不设置SetConsoleOutputCP(CP_UTF8);输出下面的内容

源代码编码测试:

'中'的原始字节: "e4b8ad"

11111测试qDebug(这里是参数)11111

22222测试qDebug()<<字符串字面量22222

"33333测试qDebug()<<QStringLiteral()33333"

"44444测试qDebug()<<QString()44444"

55555测试qDebug()<<QString().toUtf8().constData()55555

66666????qDebug()<<QString().toLocal8Bit().constData()66666

娴嬭瘯std::cout << QString().toStdString() 鍝堝搱鍝堝搱:

娴嬭瘯std::cout << QString().toUtf8().constData() 鍝堝搱鍝堝搱:

测试std::cout << QString().toLocal8Bit().constData() 哈哈哈哈:

娴嬭瘯std::cout << 瀛楃涓插瓧闈㈤噺 鍝堝搱鍝堝搱:

娴嬭瘯printf QString().toUtf8().constData(): 鍝堝搱鍝堝搱鍝堝搱鍝堝搱

测试printf QString().toLocal8Bit().constData(): 哈哈哈哈哈哈哈哈

娴嬭瘯printf 瀛楃涓插瓧闈?

设置SetConsoleOutputCP(CP_UTF8);输出下面的内容

Դ:

''ԭʼ: "e4b8ad"

11111qDebug(Dz)11111

22222qDebug()<<��22222

"33333qDebug()<<QStringLiteral()33333"

"44444qDebug()<<QString()44444"

55555qDebug()<<QString().toUtf8().constData()55555

66666????qDebug()<<QString().toLocal8Bit().constData()66666


测试std::cout << QString().toStdString() 哈哈哈哈:

测试std::cout << QString().toUtf8().constData() 哈哈哈哈:

测试printf QString().toUtf8().constData(): 哈哈哈哈哈哈哈哈

printf QString().toLocal8Bit().constData():

测试printf 字符串字面:

编译器:MinGW (g++)

Qt版本:Qt6(默认所有字符串处理使用UTF-8)

源码编码:UTF-8

系统:中文Windows(默认编码GBK/CP936)

先分析qDebug()的问题

情况一:不设置SetConsoleOutputCP(CP_UTF8)

关键问题:为什么这些中文能在GBK控制台正常显示?

答案:因为qDebug()在输出时进行了编码转换!

在Qt6中:qDebug()默认输出到控制台时,Qt会自动转换编码以适应控制台(GBK(因为它检测到Windows系统,默认转本地编码))
情况二:设置SetConsoleOutputCP(CP_UTF8)

输出乱码的原因是:

控制台现在期望UTF-8

但qDebug()仍然输出GBK(因为它检测到Windows系统,默认转本地编码)

GBK字节被控制台当作UTF-8显示 → 乱码

std::cout和printf的问题

std::cout和printf不存在qDebug()输出到控制台时自动转换编码以适应控制台,原始设置的是什么编码就输出什么编码

控制台不设置UTF-8:UTF-8被当作GBK显示 → 乱码;toLocal8Bit()即GBK码正常显示

控制台设置UTF-8:UTF-8正常显示,toLocal8Bit()即GBK直接不显示或不显示中文

另外,log4Qt和QJsonDocument这种要写入文件的工具,默认使用utf8编码,一般不会出现乱码问题;除非将文件或者控制台代码手动改成其他非UTF8编码才会出现乱码

Log4Qt 默认是用 UTF-8 往控制台写的,在 Windows 的控制台里就很容易出现中文不对,可以用下面的代码将写往控制台的编码改为和系统相关的

consoleAppender->setEncoding(QStringConverter::System);

补充

类似图中的黑方块并不是"编码被错误解码出来的汉字",而是------显示控件当前使用的字体不支持这些字符(俗称 tofu 方块)。

下图是Qt Creator 的 Application Output 面板,在没有启用Terminal窗口时,使用的是Application Output,在Qt Creator里面调试启动项目时,有可能出现显示的汉字是如下图所示的黑方块,因为在调试模式下使用的字体不支持这些字符(俗称 tofu 方块);

Qt Creator里面直接启动(Run,非调试模式)项目时,就直接显示汉字了,如下图所示

真正的"编码乱码"

典型特征是:

娴嬭瘯 锟斤拷 ��

这种是:

👉 字节被用错误编码解码了


图里的这种"黑方块 / 空方块"

特征是:

  • 原来应该是中文的位置

  • 变成统一的方块

这个在 UI 里几乎一定表示:

👉 字符是合法的 Unicode 字符

👉 但当前字体没有这个字形

也就是说:

是 font glyph 不支持,不是解码失败。

相关推荐
程序员与背包客_CoderZ24 分钟前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
钱栈up34 分钟前
Mac 开发机一键发版不用切环境:我这样改造了团队的后端部署脚本Maven编译卡住20分钟?我靠两步定位到2处隐蔽编译错误
开发语言·python·macos
william_yangshun38 分钟前
【大模型部署实战】kimi-k3-in-c 中文版:用 176KB 纯 C99 引擎在 CPU 上跑 Kimi K3 上手指南
c语言·开发语言
Sagittarius_A*1 小时前
Burst Lab | PHP 审计 14|反序列化(四):字符串逃逸与绕过技巧
开发语言·安全·php·web·反序列化
名字还没想好☜1 小时前
Go 用 slices/maps 标准库泛型函数:告别手写 Contains、Sort、去重(Go 1.21)
开发语言·后端·算法·golang·go
淼澄研学1 小时前
Python实战:基于LangChain与Chroma构建企业级RAG知识库问答系统
开发语言·python·langchain
4311媒体网1 小时前
帝国CMS网站自定义搭建技巧
服务器·开发语言·前端
布莱克6051 小时前
C++拷贝构造与拷贝赋值运算符的区别详解
开发语言·c++
lhldsg2 小时前
全民健身解决方案:从共享球场到智能运营的技术实践
java·大数据·开发语言·需求分析
归去来?2 小时前
Python 常用优雅写法
开发语言·python