Qt中線程的一種創建方式,就是使用QObject::moveToThread()函數。如下,直接上源代碼,可以把費時的任務放到doWork()方法里進行,不阻塞主線程。
1 #ifndef WORKER_H 2 #define WORKER_H 3 4 #include <QObject> 5 6 class Worker : public QObject 7 { 8 Q_OBJECT 9 10 public: 11 Worker(); 12 ~Worker(); 13 public slots: 14 void doWork(); 15 private: 16 17 }; 18 19 #endif // WORKERR_H
1 #include "Worker.h" 2 #include <QDebug> 3 4 Worker::Worker() 5 { 6 7 } 8 9 Worker::~Worker() 10 { 11 12 } 13 void Worker::doWork() 14 { 15 for (int i = 0;i < 10000;i++) 16 { 17 qDebug() << i; 18 } 19 }
需要在主程序中,關聯相應的信號和槽,
1 m_pWorker = new Worker; 2 m_pWorkerThread = new QThread(this); 3 4 connect(m_pWorkerThread, SIGNAL(started()),m_pWorker, SLOT(doWork())); 5 connect(m_pWorkerThread, SIGNAL(finished()), m_pWorker, SLOT(deleteLater())); 6 m_pWorker->moveToThread(m_pWorkerThread);
同時在析構函數中,也要進行想要的資源釋放,
1 disconnect(m_pWorkerThread, SIGNAL(started()),m_pWorker, SLOT(doWork())); 2 disconnect(m_pWorkerThread, SIGNAL(finished()), m_pWorker, SLOT(deleteLater())); 3 if (m_pWorkerThread) 4 { 5 if (m_pWorkerThread->isRunning()) 6 { 7 m_pWorkerThread->quit(); 8 m_pWorkerThread->wait(); 9 } 10 delete m_pWorkerThread; 11 m_pWorkerThread = NULL; 12 } 13 if (m_pWorker) 14 { 15 delete m_pWorker; 16 m_pWorker = NULL; 17 }
最后提一點,如果需要在doWork()函數傳遞參數中,涉及傳遞的參數是自定義的類型時,需要將其注冊為元類型。
如下的示例,1.我將需要計算的數據先進行預處理之后,發送我自定義的geoDataReady信號。
2.在線程中進行幾何計算,完成之后,又將計算完成之后的數據發送回主函數。如下。
1 qRegisterMetaType<std::vector<MyGeometry*>>("std::vector<MyGeometry* >"); 2 //在線程中進行幾何運算 3 m_pGeoWorker = new CMyWork; 4 connect(this, SIGNAL(geoDataReady(const std::vector<MyGeometry> &)), m_pGeoWorker, SLOT(get(const std::vector<MYGeometry* > &))); 5 connect(m_pGeoWorker, SIGNAL(geoResultCompleted(const std::vector<MYGeometry* > &)), this, SLOT(draw(const std::vector<MYGeometry* > &))); 6 connect(&m_geoThread, SIGNAL(finished()), m_pGeoWorker, SLOT(deleteLater())); 7 m_pGeoWorker->moveToThread(&m_geoThread); 8 m_geoThread.start();