文章可能被更新,最新位址:http://www.fearlazy.com/index.php/post/92.html
上一篇我們通過子類化QThread的方式實作了多線程。這一次将使用另一種方式實作多線程,那就是通過moveToThread将對象移動到子線程(不知道這樣表達是否準确,反正意思差不多)。moveToThread是QObject的成員函數,那麼QObject又是誰?.....連大名鼎鼎的QObject都不知道,面壁一下先。
moveToThread的函數聲明是: void moveToThread(QThread *targetThread) 。。具體的使用步驟如下:
1.從QObject派生一個類,将耗時的工作寫在該類的槽函數中。
2.将派生類對象移動到一個QThread中,該線程需要start。(這一步使用moveToThread)
3.通過信号連接配接派生類的槽函數,并通過信号觸發槽函數。(槽函數在子線程中執行)
用執行個體說話:
1.老樣子,用QtCreator建立一個基于QWidget的工程。
2.從QObject繼承一個類CWorker。并寫一個槽函數sayHello。
void CWorker::sayHello(const QString& param)
{
qDebug()<<"hello,"<<param<<QThread::currentThreadId();
}
sayHello的功能不重要,重要的是我們列印出了sayHello所在的線程。
3.在Widget的構造函數中建立一個QThread對象并start。然後建立CWorker對象,并moveTo這個線程。最後聲明一個Widget的信号sigSayHello并連接配接CWorker的sayHello槽。
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//列印出主線程
qDebug()<<"main thread:"<<QThread::currentThreadId();
//建立thread
m_pThread = new QThread;
m_pThread->start();
//建立CWorker
m_pWorker = new CWorker;
m_pWorker->moveToThread(m_pThread);
connect(this,SIGNAL(sigSayHello(QString)),m_pWorker,SLOT(sayHello(QString)));
//發射信号
emit sigSayHello("fearlazy!");
}
為了簡化代碼,直接在構造函數中發射sigSayHello信号。結果如下:
可以看到CWorker的槽函數所在的線程不是主線程,和預期的一樣。
值得注意的是我們連接配接信号槽時第五個參數是預設的,如果改為Qt::DirectConnection會是怎樣?
connect(this,SIGNAL(sigSayHello(QString)),m_pWorker,SLOT(sayHello(QString)),Qt::DirectConnection);
結果如下:
可以看到CWorker的槽函數是在主線程中執行的。因為Qt::DirectConnection連接配接方式,槽函數會和信号在一個線程。