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>
閱讀更多 KobeBryand2020 的文章