Qt线程(1) moveToThread
- 若在Qt准备使用线程类一般有两种方式(1) 采用WorkObject配合QThread进行使用 (2)继承QThread, 重载run()函数即可。
- 注:采用Qt::Concurrent之类的不在本文讨论范围内.
方式一、采用WorkObject配合QThread进行使用
- 创建一个用于计算的对象,该对象的运算相关函数防止在public slots 下:
1 //..Object.h 2 class CObject : public QObject 3 { 4 Q_OBJECT 5 public: 6 explicit CObject(QObject *parent = 0); 7 ~CObject(); 8 9 signals: 10 void sigFinish(const QString &s); //跨线程请注意使用const 11 12 public slots: 13 void Run(); 14 void Stop(); 15 16 private: 17 bool m_bStop; 18 }; 19 20 //..Object.cpp 21 CObject::CObject(QObject *parent) 22 : QObject(parent),m_bStop(false) 23 { 24 25 } 26 27 void CObject::Run() 28 { 29 int i = 0; 30 while(1) 31 { 32 if(m_bStop) 33 { 34 return; 35 } 36 qDebug()<<"Object TheradID = "<<QThread::currentThreadId(); 37 qDebug()<<"Run i = "<<i; 38 sleep(1); 39 if(++i == 10) 40 { 41 emit sigFinish("Finish");//信号是线程安全的,当然这得扯到后面的连接方式 42 } 43 } 44 } 45 46 void CObject::Stop() 47 { 48 m_bStop = true; 49 emit sigFinish("Stop");//!!按照需求添加 50 }
- 创建一个测试对象CTest
1 //..test.h 2 class CTest : public QObject 3 { 4 Q_OBJECT 5 public: 6 explicit CTest(QObject *parent = 0); 7 void Run(); 8 void Stop(); 9 10 signals: 11 12 private slots: 13 void slotFinish(const QString &); 14 15 private: 16 QList<CObject *> m_ListObj; 17 }; 18 19 //..test.cpp 20 CTest::CTest(QObject *parent) : QObject(parent) 21 { 22 23 } 24 25 void CTest::Run() 26 { 27 QThread *pThread = new QThread(this); // 只充当一个作为另个线程的入口 28 CObject *pObj = new CObject; //注意:moveToThread不能使用在双亲对象上 29 m_ListObj.append(pObj); 30 31 qDebug()<<"Current Main Run Thread = "<<QThread::currentThreadId(); 32 33 connect(pObj,SIGNAL(sigFinish(QString)),pObj,SLOT(deleteLater())); 34 connect(pObj,SIGNAL(sigFinish(QString)),pThread,SLOT(quit())); 35 connect(pObj,SIGNAL(sigFinish(QString)),this,SLOT(slotFinish(QString))); 36 37 connect(pThread,SIGNAL(started()),pObj,SLOT(Run())); 38 connect(pThread,SIGNAL(finished()),pObj,SLOT(deleteLater())); 39 40 pObj->moveToThread(pThread); 41 42 pThread->start(); 43 } 44 void CTest::Stop() 45 { 46 foreach (CObject *pObj, m_ListObj) 47 { 48 if(!QMetaObject::invokeMethod(pObj,"Stop",Qt::DirectConnection))//!!留个坑,为什么autoConnection会没反应 49 { 50 qDebug()<<"error"; 51 } 52 } 53 m_ListObj.clear(); 54 } 55 56 void CTest::slotFinish(const QString &s) 57 { 58 qDebug()<<"Main Thread Receive:"<<s; 59 }
- main.cpp
1 //..main.cpp 2 int main(int argc, char *argv[]) 3 { 4 QCoreApplication a(argc, argv); 5 CTest test; 6 test.Run(); 7 sleep(5); 8 test.Stop(); 9 return a.exec(); 10 }
- 执行结果
Well Done,方式2见Qt线程(2) QThread中使用WorkObject?
祝:玩得愉快!