Qt多線程之 moveToThread的使用

    Qt中使用多線程有兩種方式,一種是自定義的class繼承於QThread,並重寫run函數,在開始線程時,調用start()方法即可。另一種比較靈活的方式,是使用moveToThread()方法,可以靈活的將自定義類型中的成員函數(特指槽函數)放在獨立的線程中運行。下面只是簡單的附一個例子,介紹moveToThread的使用,以及如何優雅的結束循環線程。

// worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class worker : public QObject
{
    Q_OBJECT
public:
    explicit worker(QObject *parent = NULL);

signals:
    void result(int num);
public slots:
    void dowork();
public:
    enum WorkerStatus{
        START_WORKER = false,
        FINISH_WORKER = true
    };
    WorkerStatus flag;
};

#endif // WORKER_H
// worker.cpp

#include "worker.h"
#include <QDebug>
#include <QThread>
#include <windows.h>
worker::worker(QObject *parent) : QObject(parent)
{
    flag = FINISH_WORKER;
}


void worker::dowork()
{
    for(int i =0;i < (0x01 << 16);i++){
        //qDebug() << i;
        if(flag == FINISH_WORKER) break;
        emit result(i);
        ::Sleep(1);
    }
}
// widget.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class worker : public QObject
{
    Q_OBJECT
public:
    explicit worker(QObject *parent = NULL);

signals:
    void result(int num);
public slots:
    void dowork();
public:
    enum WorkerStatus{
        START_WORKER = false,
        FINISH_WORKER = true
    };
    WorkerStatus flag;
};

#endif // WORKER_H
// widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "widget.h"
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_pWorker = new worker;
    m_pWorkerThread = new QThread(this);
}

Widget::~Widget()
{
    disconnect(m_pWorkerThread, SIGNAL(started()),m_pWorker, SLOT(dowork()));
    disconnect(m_pWorkerThread, SIGNAL(finished()), m_pWorker, SLOT(deleteLater()));
    if (m_pWorker)
    {
        m_pWorker->flag = worker::FINISH_WORKER;
        delete m_pWorker;
        m_pWorker = NULL;
    }
    if (m_pWorkerThread)
    {
        if (m_pWorkerThread->isRunning())
        {
            m_pWorkerThread->quit();
            m_pWorkerThread->wait();
        }
        delete m_pWorkerThread;
        m_pWorkerThread = NULL;
    }
    delete ui;
}


void Widget::on_startpushButton_clicked()
{

    m_pWorker->flag = worker::START_WORKER;
    connect(m_pWorkerThread,SIGNAL(started()),m_pWorker,SLOT(dowork()));
    connect(m_pWorkerThread,SIGNAL(finished()),m_pWorker,SLOT(deleteLater()));
    connect(m_pWorker,SIGNAL(result(int)),this,SLOT(showResult(int)));
    m_pWorker->moveToThread(m_pWorkerThread);
    m_pWorkerThread->start();
}

void Widget::on_stoppushButton_clicked()
{
    m_pWorker->flag = worker::FINISH_WORKER;
    disconnect(m_pWorkerThread, SIGNAL(started()),m_pWorker, SLOT(dowork()));
    disconnect(m_pWorkerThread, SIGNAL(finished()), m_pWorker, SLOT(deleteLater()));

    if (m_pWorkerThread->isRunning())
    {
        m_pWorkerThread->quit();
        m_pWorkerThread->wait();
    }
}

void Widget::showResult(int result){
    ui->label->setText(QString::number(result));
}

程序運行如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章