利用繼承QObject方法創建多線程,主要的步驟有一下幾點:(注意:退出線程循環後,還要調用QThread::quit()函數,該線程才會觸發QThread::finished()信號)
a1:首先創建一個類MyThread,基類為QObject。
a2:在類MyThread中創建一個槽函數,用於運行多線程裡面的代碼。所有耗時代碼,全部在這個槽函數里面運行。
a3:實例一個QThread線程對象(容器),將類MyThread的實例對象轉到該容器中,用函數void QObject::moveToThread(QThread *thread);
myObjectThread->moveToThread(firstThread);
a4:用一個信號觸發該多線程槽函數,比如用QThread::started()信號。
connect(firstThread,SIGNAL(started()),myObjectThread,SLOT(startThreadSlot()));
a5:用信號QThread::finished綁定槽函數QThread::deleteLatater(),在線程退出時,銷燬該線程和相關資源。
connect(firstThread,SIGNAL(finished()),firstThread,SLOT(deleteLater()));
a6:所有線程初始化完成後,啟動函數QThread::start()開啟多線程,然後自動觸發多線程啟動信號QThread::started()。
具體的教程如下圖所示:
1.1新建一個widget工程,不要勾選ui界面。然後分別在mythread.h,mythread.cpp,widget.h,widget.cpp,main.cpp分別添加如下代碼。
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <qobject>
class MyThread : public QObject
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void closeThread();
signals:
public slots:
void startThreadSlot();
private:
volatile bool isStop;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <qdebug>
#include <qthread>
MyThread::MyThread(QObject *parent) : QObject(parent)
{
isStop = false;
}
void MyThread::closeThread()
{
isStop = true;
}
void MyThread::startThreadSlot()
{
while (1)
{
if(isStop)
return;
qDebug()<
QThread::sleep(1);
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <qwidget>
#include <qvboxlayout>
#include <qpushbutton>
#include <qthread>
#include "mythread.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
void createView();
private slots:
void openThreadSlot();
void closeThreadSlot();
void finishedThreadSlot();
private:
QVBoxLayout *mainLayout;
QThread *firstThread;
MyThread *myObjectThread;
};
#endif // WIDGET_H
widget.cpp
#include <qdebug>
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
createView();
}
Widget::~Widget()
{
}
void Widget::createView()
{
/*UI界面*/
mainLayout = new QVBoxLayout(this);
QPushButton *openThreadBtn = new QPushButton(tr("打開線程"));
QPushButton *closeThreadBtn = new QPushButton(tr("關閉線程"));
mainLayout->addWidget(openThreadBtn);
mainLayout->addWidget(closeThreadBtn);
mainLayout->addStretch();
connect(openThreadBtn,SIGNAL(clicked(bool)),this,SLOT(openThreadSlot()));
connect(closeThreadBtn,SIGNAL(clicked(bool)),this,SLOT(closeThreadSlot()));
}
void Widget::openThreadSlot()
{
/*開啟一條多線程*/
qDebug()<
firstThread = new QThread; //線程容器
myObjectThread = new MyThread;
myObjectThread->moveToThread(firstThread); //將創建的對象移到線程容器中
connect(firstThread,SIGNAL(finished()),myObjectThread,SLOT(deleteLater())); //終止線程時要調用deleteLater槽函數
connect(firstThread,SIGNAL(started()),myObjectThread,SLOT(startThreadSlot())); //開啟線程槽函數
connect(firstThread,SIGNAL(finished()),this,SLOT(finishedThreadSlot()));
firstThread->start(); //開啟多線程槽函數
qDebug()<
}
void Widget::closeThreadSlot()
{
qDebug()<
if(firstThread->isRunning())
{
myObjectThread->closeThread(); //關閉線程槽函數
firstThread->quit(); //退出事件循環
firstThread->wait(); //釋放線程槽函數資源
}
}
void Widget::finishedThreadSlot()
{
qDebug()<
}
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();
}
"
閱讀更多 KobeBryand2020 的文章