一個簡單的多線程實例(類QThread)(第一種方法)

Qt開啟多線程,主要用到類QThread。有兩種方法,第一種用一個類繼承QThread,然後重新改寫虛函數run()。當要開啟新線程時,只需要實例該類,然後調用函數start(),就可以開啟一條多線程。第二種方法是繼承一個QObject類,然後利用moveToThread()函數開啟一個線程槽函數,將要花費大量時間計算的代碼放入該線程槽函數中

下面我總結的主要是第一種方法。(注意:只有在run()函數里面才是新的線程,所有複雜邏輯都應該在run()函數里面做。當run()函數運行完畢後,該線程生命週期結束。)

創建多線程步驟如下:

a1新建一個類MyThread,基類為QThread。

a2重寫類MyThread的虛函數void run();,即新建一個函數protected void run(),然後對其進行定義。

a3在需要用到多線程的地方,實例MyThread,然後調用函數MyThread::start()後,則開啟一條線程,自動運行函數run()。

a4當停止線程時,調用MyThread::wait()函數,等待線程結束,並且回收線程資源。

1.1新建一個widget工程,不要勾選ui界面。然後分別在mythread.h,mythread.cpp,widget.h,widget.cpp,main.cpp分別添加如下代碼。

<code>//main.cpp
#include "widget.h"
#include <qapplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.resize(960, 640);
w.show();

return a.exec();

}
/<qapplication>/<code>
<code>//mythread.h
#ifndef MYTHREAD
#define MYTHREAD

#include <qthread>

class MyThread : public QThread
{
private:
volatile bool m_bStop;

protected:
void run();

public:
MyThread();
void CloseThread();
};

#endif // MYTHREAD
/<qthread>/<code>
<code>//mythread.cpp
#include <qdebug>
#include "mythread.h"

MyThread::MyThread()
{
m_bStop = false;
}

void MyThread::run()
{
qDebug() << "mythread current thread id: " << QThread::currentThreadId() << "\\n";
}

void MyThread::CloseThread()
{
m_bStop = true;
}
/<qdebug>/<code>
<code>//widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <qwidget>

#include <qvboxlayout>
#include <qpushbutton>
#include "mythread.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;

public:
void CreateView();

private slots:
void OpenThreadBtnSlot();
void CloseThreadBtnSlot();
void FinishThreadSlot();

private:
QVBoxLayout *m_pMainLayout;
MyThread *m_pThread;
};

#endif // WIDGET_H
/<qpushbutton>/<qvboxlayout>/<qwidget>/<code>
<code>//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <qdebug.h>
#include <windows.h>

class QDebug;

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
CreateView();
}


Widget::~Widget()
{
delete ui;
}

void Widget::CreateView()
{
QPushButton *pOpenBtn = new QPushButton(tr("打開線程"));
QPushButton *pCloseBtn = new QPushButton(tr("關閉線程"));
m_pMainLayout = new QVBoxLayout(this);
m_pMainLayout->addWidget(pOpenBtn);
m_pMainLayout->addWidget(pCloseBtn);
m_pMainLayout->addStretch();

connect(pOpenBtn, SIGNAL(clicked(bool)), this, SLOT(OpenThreadBtnSlot()));
connect(pCloseBtn, SIGNAL(clicked(bool)), this, SLOT(CloseThreadBtnSlot()));

m_pThread = new MyThread();
connect(m_pThread, SIGNAL(finished()), this, SLOT(FinishThreadSlot()));
}

void Widget::OpenThreadBtnSlot()
{
m_pThread->start();
qDebug() << tr("主線程id: ") << QThread::currentThreadId() << "\\n";
}

void Widget::CloseThreadBtnSlot()
{
m_pThread->CloseThread();
m_pThread->wait();
}

void Widget::FinishThreadSlot()
{
qDebug() << tr("完成信號觸發") << "\\n";
}
/<windows.h>/<qdebug.h>/<code>


分享到:


相關文章: