Qt线程致Qt Creator短暂无响应及QThread项目输出异常求助
解决QThread演示项目的两个小问题:输出位置与Creator卡顿
看起来你在用Qt Creator 4.5 + Qt 5.7做QThread小Demo时遇到了俩麻烦:输出跑到Creator自带的Application Output面板里,而且点击按钮时Creator还会短暂无响应。我来帮你逐一搞定~
一、为啥输出在Application Output而非外部控制台?
这是Qt Creator的默认调试行为——运行GUI程序时,它会把stdout和stderr的输出重定向到内部的Application Output面板,方便你在同一个窗口里查看调试信息。如果非要用外部控制台窗口,有两种办法:
通过Creator设置调整:
- 点击左侧侧边栏的「项目」按钮(那个小扳手图标)
- 切换到「Run」选项卡
- 找到「Console」板块,勾选「Run in terminal」(部分版本叫「External terminal」)
- 重新编译运行,就能看到独立的控制台窗口弹出,输出会显示在这里
通过.pro文件配置:
在项目的.pro文件中添加一行代码:CONFIG += console加了之后,哪怕是GUI程序,启动时也会自带一个控制台窗口,适合调试阶段使用,发布时可以删掉这行配置。
二、Qt Creator短暂无响应的原因及解决办法
这种卡顿几乎100%是因为主线程(UI线程)被阻塞了——十有八九是你对QThread的用法有误,比如没真正启动新线程,反而在主线程里执行了耗时操作,或者用了wait()这类会阻塞主线程的方法。
正确的QThread用法(推荐用moveToThread模式)
Qt官方更推荐使用QObject::moveToThread()的方式实现多线程,而非直接继承QThread(除非你需要修改线程的事件循环逻辑)。下面是适配你需求的示例代码:
1. 工作类定义(mythread.h)
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> // 处理A按钮逻辑的工作类 class WorkerA : public QObject { Q_OBJECT public slots: void doWork() { // 线程要执行的任务,比如打印A qDebug() << "A"; } }; // 处理B按钮逻辑的工作类 class WorkerB : public QObject { Q_OBJECT public slots: void doWork() { // 线程要执行的任务,比如打印B qDebug() << "B"; } }; #endif // MYTHREAD_H
2. MainWindow中的线程管理(mainwindow.cpp)
#include "mainwindow.h" #include "ui_mainwindow.h" #include "mythread.h" #include <QThread> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 配置WorkerA和对应的线程 WorkerA *workerA = new WorkerA; QThread *threadA = new QThread(this); workerA->moveToThread(threadA); // 将工作类移到新线程中 // 按钮点击时触发Worker的工作槽 connect(ui->threadA, &QPushButton::clicked, workerA, &WorkerA::doWork); // 线程结束时自动销毁Worker,避免内存泄漏 connect(threadA, &QThread::finished, workerA, &QObject::deleteLater); // 启动线程 threadA->start(); // 同理配置WorkerB WorkerB *workerB = new WorkerB; QThread *threadB = new QThread(this); workerB->moveToThread(threadB); connect(ui->threadB, &QPushButton::clicked, workerB, &WorkerB::doWork); connect(threadB, &QThread::finished, workerB, &QObject::deleteLater); threadB->start(); // Quit按钮直接关闭窗口 connect(ui->quit, &QPushButton::clicked, this, &MainWindow::close); } MainWindow::~MainWindow() { // 窗口关闭时,先关闭所有线程 for (QThread *thread : findChildren<QThread*>()) { thread->quit(); thread->wait(); // 等待线程完全结束再销毁 } delete ui; }
你可能踩的坑:错误的QThread用法
如果你的代码是下面这样,必然会导致主线程阻塞:
// 错误示例!请勿这么写! void MainWindow::on_threadA_clicked() { MyThreadA thread; thread.run(); // 直接调用run()不会开启新线程,代码在主线程执行 thread.wait(); // 这行直接阻塞主线程直到线程结束,UI完全无法响应 }
这种写法等于没用到多线程,点击按钮后代码全在主线程运行,哪怕只是简单打印,只要重复几次就会让UI卡顿,Qt Creator因为等不到主线程响应,自然会短暂无响应。
总结
- 要输出到外部控制台:要么修改Creator的Run设置,要么给
.pro文件添加CONFIG += console - 解决卡顿:一定要正确使用QThread,避免阻塞主线程,推荐用
moveToThread的方式分离业务逻辑和线程管理
内容的提问来源于stack exchange,提问作者jwm
相关产品推荐
相关产品推荐

