天天看點

Qt線程之moveToThread

文章可能被更新,最新位址: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信号。結果如下:

Qt線程之moveToThread

    可以看到CWorker的槽函數所在的線程不是主線程,和預期的一樣。

    值得注意的是我們連接配接信号槽時第五個參數是預設的,如果改為Qt::DirectConnection會是怎樣?

connect(this,SIGNAL(sigSayHello(QString)),m_pWorker,SLOT(sayHello(QString)),Qt::DirectConnection);
      

    結果如下:

Qt線程之moveToThread

   可以看到CWorker的槽函數是在主線程中執行的。因為Qt::DirectConnection連接配接方式,槽函數會和信号在一個線程。