1. 程式人生 > 其它 >Qt庫 執行緒

Qt庫 執行緒

技術標籤:學習qt

Qt庫 執行緒

方式一、繼承QThread

步驟:

  1. 自定義繼承於QThread的執行緒類
  2. 定義執行緒物件
  3. 呼叫start()介面啟動執行緒
  4. 定義執行緒結束槽函式
  5. 定義執行緒關閉槽函式
  6. 繫結執行緒結束訊號與執行緒結束槽函式
  7. 繫結視窗關閉訊號和執行緒關閉槽函式

程式碼示例:

  1. 自定義執行緒類
/*mythred.h*/
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject * parent=0);
    ~MyThread();
protected:
    void run();
signals:
    void isDone();
public slots:
};
#endif // MYTHREAD_H
/*mythred.cpp*/
#include "mythread.h"
MyThread::MyThread(QObject * parent)
{
}
MyThread::~MyThread()
{
}
void MyThread::run()
{
    sleep(5);
    emit isDone();
}
  1. 介面顯示類
/*widget.h*/
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include"mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void dealTimeout();
    void dealDone();
    void stopThread();
private slots:
    void on_pushButton_clicked();
private:
    Ui::Widget *ui;
    QTimer *myTimer;
    MyThread *thread;
};
#endif // WIDGET_H
/*widget.cpp*/
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QDebug>
#include<QThread>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    myTimer = new QTimer(this);
    thread = new MyThread(this);
    connect(thread, &MyThread::isDone,this,&Widget::dealDone);
    connect(this, &Widget::destroyed, this, &Widget::stopThread);
    connect(myTimer, &QTimer::timeout, this, &Widget::dealTimeout);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    if(!myTimer->isActive()){
        myTimer->start(100);
    }
    thread->start();
}
void Widget::dealTimeout()
{
    static int i = 0;
    i++;
    ui->lcdNumber->display(i);
}
void Widget::dealDone()
{
    qDebug() << "it is over";
    myTimer->stop();
}
void Widget::stopThread()
{
    thread->quit();
    thread->wait();
}

  1. 介面佈局
    在這裡插入圖片描述

方式二、繼承QObject

步驟:

  1. 自定義繼承於QObject的執行緒類MyThread
  2. 定義自定義執行緒類(子執行緒)及介面類(主執行緒)訊號
  3. 建立QThread主執行緒物件和自定義子執行緒物件
  4. 繫結子執行緒訊號與主執行緒定義的訊號處理函式
  5. 繫結主執行緒訊號與子執行緒執行緒函式
  6. 把自定義執行緒類MyThread加到主執行緒QThread

程式碼示例:

  1. 自定義執行緒類

    /*mythread.h*/
    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    #include <QObject>
    class MyThread : public QObject
    {
        Q_OBJECT
    public:
        explicit MyThread(QObject *parent = nullptr);
        ~MyThread();
        void run();
        void start();
        void stop();
    signals:
        void myThreadrun();
    public slots:
    private:
        bool isRun;
    };
    #endif // MYTHREAD_H
    
    /*mythread.cpp*/
    #include "mythread.h"
    #include<QDebug>
    #include<QThread>
    MyThread::MyThread(QObject *parent) : QObject(parent)
    {
     }
    MyThread:: ~MyThread()
    {
    }
    void MyThread::start()
    {
        qDebug()<<"start";
        this->isRun = true;
    }
    void MyThread::stop()
    {
        qDebug()<<"stop";
        this->isRun = false;
    }
    void MyThread::run()
    {
        while(isRun){
            QThread::sleep(1);
            emit myThreadrun();
            qDebug() << "子執行緒:" << QThread::currentThread();
            if(!isRun)
                break;
        }
    }
    
  2. 介面顯示類

    /*widget.h*/
    #ifndef WIDGET_H
    #define WIDGET_H
    #include <QWidget>
    #include  "mythread.h"
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    class Widget : public QWidget
    {
        Q_OBJECT
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
        void dealSignal();
        void dealClose();
    signals:
        void startThread();
    private slots:
        void on_pushButtonStart_clicked();
        void on_pushButton_clicked();
    private:
        Ui::Widget *ui;
        MyThread *myT;
        QThread *thread;
    };
    #endif // WIDGET_H
    
    /*widget.cpp*/
    #include "widget.h"
    #include "ui_widget.h"
    #include<QThread>
    #include<QTimer>
    #include<QDebug>
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        myT = new MyThread;
        thread = new QThread(this);
        myT->moveToThread(thread);
        connect(myT,&MyThread::myThreadrun,this,&Widget::dealSignal);
        connect(this,&Widget::startThread,myT,&MyThread::run);
        qDebug() << "主執行緒:" << QThread::currentThread();
        connect(this,&Widget::destroyed,this,&Widget::dealClose);
    }
    Widget::~Widget()
    {
        delete ui;
    }
    void Widget::dealSignal()
    {
        static int i = 0;
        i++;
        ui->lcdNumber->display(i);
    }
    void Widget::on_pushButtonStart_clicked()
    {
        if(thread->isRunning())  {
            return;
        }
        thread->start();
        myT->start();
        emit startThread();
    }
    void Widget::on_pushButton_clicked()
    {
        if(!thread->isRunning())  {
            return;
        }
        myT->stop();
        thread->quit();
        thread->wait();
    }
    void Widget::dealClose()
    {
        on_pushButton_clicked();
        delete myT;
    }
    
  3. 介面佈局
    在這裡插入圖片描述