標籤:
首先必須明確的是,Qt中的線程使用是相對複雜的,並不像C#中那麼隨意,特別是結合串口、網路編程等,使用時稍有不慎就會出問題,然後Qt裡面經常出了問題就直接崩潰(這個真是誰用誰知道),所以如果在功能上用非同步方式能做到其實就沒必要自己去開線程,當然如果自己寫的函數比較耗時(比如不斷地迴圈做操作之類的)就無法避免使用線程了。
Qt中一般將耗時操作單獨放在一個類中實現,在主線程中建立類對象,然後將這個對象移到子線程中,主線程與子線程間的通訊主要通過訊號和槽實現。另外對象是在主線程中建立的,對象中的成員都屬於主線程,在主、子線程中都可以直接存取,不過如果你把對象中的成員也移到子線程中,那麼在主線程就不能直接存取這個成員了。
下面是一個使用執行個體。
class ThreadManager : public QObject{ Q_OBJECT QThread workerThread;public: ThreadManager(); ~ThreadManager(); MyWorker * worker;signals: void start();public slots: void emitstart(); void emitstop(); void printThreadId(int count);};
ThreadManager::ThreadManager(){ worker = new MyWorker(); worker->moveToThread(&workerThread); connect(this,SIGNAL(start()),worker,SLOT(Start())); connect(worker,SIGNAL(invokeParentThreadMethod(int)),this,SLOT(printThreadId(int))); workerThread.start();}ThreadManager::~ThreadManager(){ workerThread.quit();}void ThreadManager::emitstart(){ emit start();}void ThreadManager::emitstop(){ worker->stoped = true; qDebug()<<"停止";}void ThreadManager::printThreadId(int count){ //worker->stoped = true; qDebug()<<QThread::currentThreadId()<<"\t"<<count;}
ThreadManager 用來開啟一個新的線程,然後在這個線程裡面執行其他動作,下面是執行操作的類 MyWorker。
class MyWorker : public QObject{ Q_OBJECTpublic: explicit MyWorker(QObject *parent = 0); bool stoped;signals: void invokeParentThreadMethod(int count);public slots: void Start();};
MyWorker::MyWorker(QObject *parent) : QObject(parent){ stoped = false;}void MyWorker::Start(){ int count =0; stoped = false; while(!stoped) { qDebug()<<QThread::currentThreadId()<<"\t"<<count++; emit invokeParentThreadMethod(count); QThread::msleep(500); }}
再看看我們在主線程中如何使用的
QObject* win = engine.rootObjects()[0]; QObject* Button_Start = win->findChild<QObject*>("Button_Start"); QObject* Button_Stop = win->findChild<QObject*>("Button_Stop"); ThreadManager* therad = new ThreadManager(); QObject::connect(Button_Start,SIGNAL(clicked()),therad,SLOT(emitstart())); QObject::connect(Button_Stop,SIGNAL(clicked()),therad,SLOT(emitstop()));
這裡只是一個很簡單的線程使用樣本,在串口、網路編程時往往涉及到線程同步、資源共用、線程通訊等問題,比如子線程還在使用資源主線程卻將資源釋放了或是線程間通訊時傳過去的資料發生了變化等等,具體情況只有結合自己經驗去分析了。
Qt Quick快速入門之線程基礎