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));
}
程序運行如下: