Qt使用線程主要有兩種方法:
方法一:繼承QThread,重寫run()的方法
QThread是一個非常便利的跨平台的對平台原生線程的抽象。啟動一個線程是很簡單的。讓我們看一個簡短的代碼:生成一個在線程內輸出"hello"並退出的線程。
// hellothread/hellothread.h
class HelloThread : public QThread
{
Q_OBJECT
private:
void run();
};
我們從QThread派生出一個類,並重新實現run方法。
// hellothread/hellothread.cpp
void HelloThread::run()
{
qDebug() << "hello from worker thread " << thread()->currentThreadId();
}
run方法中包含將在另一個線程中運行的代碼。在本例中,一個包含線程ID的消息被打印出來。 QThread::start()將在另一個線程中被調用。
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
HelloThread thread;
thread.start();
qDebug() << "hello from GUI thread " << app.thread()->currentThreadId();
thread.wait(); // do not exit before the thread is completed!
return 0;
}
另一種方法:moveToThread的方法
其實,這個方法太簡單,太好用了。定義一個普通的QObject派生類,然后將其對象move到QThread中。使用信號和槽時根本不用考慮多線程的存在。也不用使用QMutex來進行同步,Qt的事件循環會自己自動處理好這個。
/*!
* \file main.cpp
*
* Copyright (C) 2010, dbzhang800
* All rights reserved.
*
*/
#include <QtCore/QCoreApplication>
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <QtCore/QDebug>
class Dummy:public QObject
{
Q_OBJECT
public:
Dummy(QObject* parent=0):QObject(parent) {}
public slots:
void emitsig()
{
emit sig();
}
signals:
void sig();
};
class Object:public QObject
{
Q_OBJECT
public:
Object(){}
public slots:
void slot()
{
qDebug()<<"from thread slot:" <<QThread::currentThreadId();
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"main thread:"<<QThread::currentThreadId();
QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread);
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();
dummy.emitsig();
return a.exec();
}
運行結果,slot不在主線程
main thread: 0x1a5c
from thread slot: 0x186c
其基本用法包含下面幾步:
QThread *thread = new QThread;
threads *thread_slot = new threads;
//移動到另一線程
thread_slot->moveToThread(thread);
thread->start();
//兩個類之間的相互通信
QObject::connect(this, SIGNAL(trans_signal()), thread_slot, SLOT(th_trans_code()));