需要注意的是,Qt 的 GUI 相关的实现以及更新只能在主线程中完成。
简易线程创建并使用
auto tempHandleDicomInfoThread = new QThread();
connect(tempHandleDicomInfoThread, &QThread::started, [=]() {
qDebug() << "tempHandleDicomInfoThread started" << tempHandleDicomInfoThread->currentThreadId();
foo();//do something
tempHandleDicomInfoThread->quit();
});
connect(tempHandleDicomInfoThread, &QThread::finished, [=]() {
qDebug() << "tempHandleDicomInfoThread finished" << tempHandleDicomInfoThread->currentThreadId();
tempHandleDicomInfoThread->deleteLater();
});
tempHandleDicomInfoThread->start();
这里可以体现出创建一个线程公有的步骤:
- 创建一个 QThread 线程对象
- start 这个线程
- 在运行完成后 quit
- 并在线程发出 finished 信号后 delete 这个线程
继承 QThread 实现多线程
许多博客中写明了并不推荐该用法而是推荐下面的 moveToThread 实现方法,具体原因还在了解中。
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread(QObject* parent = nullptr);
signals:
void signal_mThread();//自定义发送的信号
public slots:
void slotMyThread();//自定义槽
protected:
void run() override;
};
#include <mythread.h>
Controller::Controller(QObject *parent) : QObject(parent)
{
myThrd = new MyThread;
connect(myThrd, &MyThread::signal_mThread, this, &Controller::handleResults);
connect(myThrd, &QThread::finished, this, &QObject::deleteLater); //该线程结束时销毁
connect(this, &Controller::operate, myThrd, &MyThread::myThreadSlot);
myThrd->start();
emit operate();
}
Controller::~Controller()
{
myThrd->quit();
myThrd->wait();
}
这里我们创建了一个基于 QThread 的类,来实现数据的处理。通过接口 operate() 向其传入数据,通过 signal_mThread() 传出处理完成的数据。
moveToThread
//moveToThread
class Worker : public QObject {
Q_OBJECT
public:
Worker();
~Worker();
public slots:
void process(){
qDebug()<<"hello world";
emit finfished();
}
signals:
void finished();
void error(QString err);
private:
// add your variables here
};
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
QThread 的使用应该与常规线程实例非常相似:
- 准备一个对象 QObject 类,其中包含所有所需的功能
- 创建一个新的 QThread 实例,使用 QObject 实例的 moveToThread(QThread*) 将 QObject 推送到该实例上
- 并在 QThread 实例上调用 start()
线程同步
//互斥锁 QMutex
class Worker : public QObject {
Q_OBJECT
public:
Worker();
~Worker();
void setMutex(QMutex &mutex){mMutex = mutex};
public slots:
void process(){
mMutex->lock();
qDebug()<<"hello world";
emit finfished();
mMutex->unlock();
}
signals:
void finished();
void error(QString err);
private:
QPointer<QMutex> mMutex;
};
void foo(){
QMutex mutex;
QThread* thread = new QThread;
auto worker1 = new worker();
auto worker2 = new worker();
//connect ......
worker1->setMutex(mutex);
worker2->setMutex(mutex);
worker1->start();
worker2->start();
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。