375 字
1 分钟
【QT】多线程
2026-06-11

GUI 线程(主线程)负责事件循环与绘制,不应执行长时间阻塞操作。耗时任务应放到工作线程,通过信号槽或 QMetaObject::invokeMethod 将结果回传主线程更新界面。

QThread 两种用法#

用法一:继承 QThread,重写 run()#

class WorkerThread : public QThread
{
Q_OBJECT
protected:
void run() override {
// 耗时计算,不要直接操作 GUI
emit resultReady(data);
}
signals:
void resultReady(const QString &data);
};
WorkerThread *thread = new WorkerThread;
connect(thread, &WorkerThread::resultReady, this, &MainWindow::onResult);
connect(thread, &WorkerThread::finished, thread, &QObject::deleteLater);
thread->start();

用法二:moveToThread(推荐)#

QObject 工作对象移到线程,QThread 只管理事件循环:

QThread *thread = new QThread;
Worker *worker = new Worker; // 普通 QObject 子类,含 doWork() 槽
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &Worker::doWork);
connect(worker, &Worker::finished, thread, &QThread::quit);
connect(worker, &Worker::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QObject::deleteLater);
thread->start();

原则moveToThread 之后,只在正确线程通过信号槽调用 worker 的槽;不要从其他线程直接调用 worker 的成员函数(除非线程安全且文档允许)。

QtConcurrent#

基于线程池的简化 API,适合一次性并行计算:

#include <QtConcurrent>
#include <QFutureWatcher>
QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
connect(watcher, &QFutureWatcher<int>::finished, this, [watcher]() {
qDebug() << watcher->result();
});
watcher->setFuture(QtConcurrent::run([]() { return heavyCompute(); }));

QtConcurrent::map / filtered / mapped 可处理容器。

线程同步#

用途
QMutex + QMutexLocker互斥锁
QReadWriteLock读多写少
QSemaphore计数信号量
QWaitCondition条件变量
QAtomicInt原子操作

尽量缩小锁粒度;UI 更新仍在主线程完成。

连接类型与线程#

工作线程 emit signal() → 主线程槽:使用默认 AutoConnection 或显式 QueuedConnection,槽在主线程执行,可安全更新控件。

connect(worker, &Worker::progress, this, &MainWindow::onProgress,
Qt::QueuedConnection);

禁止事项#

  • 不要在 run() 或子线程中直接 delete 仍在主线程使用的 QWidget
  • 不要在工作线程创建带父对象的 GUI 控件(父对象通常在主线程)。
  • QSqlDatabase 连接不能跨线程共享同一连接名;每线程独立 addDatabase 或连接池。

QThread 生命周期#

thread->quit(); // 退出事件循环
thread->wait(); // 等待线程结束

析构前确保线程已停止,避免野指针。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【QT】多线程
https://lysj.work/posts/studynotes/qt/qt多线程/
作者
Sekiro
发布于
2026-06-11
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录