Qt创建线程的方法
方法1:继承 QThread
并重写 run()
(经典方法)
#include <QThread>
#include <QDebug>
class WorkerThread : public QThread {
Q_OBJECT
protected:
void run() override {
qDebug() << "子线程ID:" << QThread::currentThreadId();
// 在这里执行耗时任务
for (int i = 0; i < 5; ++i) {
msleep(500); // 模拟耗时操作
qDebug() << "工作进度:" << i;
}
}
};
// 使用线程
WorkerThread *thread = new WorkerThread();
connect(thread, &WorkerThread::finished, thread, &QObject::deleteLater); // 自动清理
thread->start(); // 启动线程
方法2:moveToThread
+ 信号槽(推荐方法,符合Qt事件模型)
#include <QObject>
#include <QThread>
#include <QDebug>
class Worker : public QObject {
Q_OBJECT
public slots:
void doWork() {
qDebug() << "子线程ID:" << QThread::currentThreadId();
for (int i = 0; i < 5; ++i) {
QThread::msleep(500);
qDebug() << "工作进度:" << i;
}
emit workFinished();
}
signals:
void workFinished();
};
// 使用线程
QThread *thread = new QThread();
Worker *worker = new Worker();
worker->moveToThread(thread); // 关键:将对象移到新线程
connect(thread, &QThread::started, worker, &Worker::doWork); // 线程启动触发工作
connect(worker, &Worker::workFinished, thread, &QThread::quit); // 结束线程
connect(thread, &QThread::finished, thread, &QObject::deleteLater); // 清理线程
connect(thread, &QThread::finished, worker, &QObject::deleteLater); // 清理Worker
thread->start(); // 启动线程事件循环
方法3:使用 QtConcurrent
(简化并行任务)
#include <QtConcurrent>
#include <QDebug>
void simpleTask() {
qDebug() << "子线程ID:" << QThread::currentThreadId();
for (int i = 0; i < 5; ++i) {
QThread::msleep(500);
qDebug() << "任务进度:" << i;
}
}
// 启动线程
QFuture<void> future = QtConcurrent::run(simpleTask);
方法4:使用 QRunnable
+ QThreadPool
(任务池)
#include <QRunnable>
#include <QThreadPool>
#include <QDebug>
class Task : public QRunnable {
public:
void run() override {
qDebug() << "子线程ID:" << QThread::currentThreadId();
for (int i = 0; i < 5; ++i) {
QThread::msleep(500);
qDebug() << "任务进度:" << i;
}
}
};
// 提交任务到全局线程池
Task *task = new Task();
task->setAutoDelete(true); // 自动删除任务对象
QThreadPool::globalInstance()->start(task);
关键区别总结:
方法 | 适用场景 | 线程管理 | 通信方式 |
---|---|---|---|
继承QThread | 简单独立任务 | 手动管理线程 | 需自定义信号槽 |
moveToThread | 复杂对象(需事件循环/信号槽) | 自动事件循环 | 内置信号槽 |
QtConcurrent | 单次函数调用(无状态任务) | 自动线程池管理 | 通过QFuture |
QRunnable | 高并发短任务(线程池复用) | 线程池管理 | 需手动实现 |
注意事项:
- 线程安全:跨线程访问数据时使用互斥锁(
QMutex
)或信号槽。 - 事件循环:
moveToThread
依赖线程的事件循环(通过exec()
启动)。 - 资源释放:使用
QObject::deleteLater
安全释放对象。 - 全局线程池:
QtConcurrent
和QRunnable
默认使用QThreadPool::globalInstance()
。
对于需要事件循环的复杂任务,moveToThread
是最推荐的方式。