1. 程式人生 > 其它 >QT應用(7)-多執行緒-QT4.7以後的版本

QT應用(7)-多執行緒-QT4.7以後的版本

技術標籤:qt

與前篇4.7以前版本一塊看會更有啟發。
demo示例

過程如下圖所示:

注意事項: 1.建構函式不能指定父物件 pmyt_ =new MyThread;不能寫成pmyt_ =new MyThread(this)
2.子執行緒不處理ui視窗 不能有QMessageBox之類。只處理資料相關的操作。
//1.自定義執行緒pmyt_ =new MyThread;
//2.系統執行緒 pt_=new QThread(this);
//3.關聯兩個 pmyt_->moveToThread(pt_);
//4.啟動系統執行緒pt_->start()
//5.自定義執行緒 訊號->槽函式工作

//6.關閉執行緒pt_->quit() pt_->wait()

myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <QThread>
#include<QDebug>
//1.派生於QObject
//2.執行緒處理函式為自定義doMyWork(),不再是run()
class MyThread : public QObject
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr);

    bool isStop;
    void setFlag(bool flag);

signals:
     void mySingal();

public slots:
      // 執行緒處理函式
      void doMyWork();





};

#endif // MYTHREAD_H


myThread.cpp

#include "mythread.h"
//不可以有UI相關的類
MyThread::MyThread(QObject *parent) : QObject(parent)
{
    isStop=false;
}

 void MyThread::doMyWork()
 {
     while(!isStop)
     {
         QThread::sleep(1);
         emit mySingal();
         qDebug()<<"子執行緒號:"<<QThread::currentThread();

         if(isStop)
         {
             break;
         }
     }
 }
  void MyThread::setFlag(bool flag)
  {
      isStop=flag;
  }


主函式呼叫

#include "mainwindow.h"
#include "ui_mainwindow.h"

//1.自定義執行緒pmyt_ =new MyThread;
//2.系統執行緒 pt_=new QThread(this);
//3.關聯兩個 pmyt_->moveToThread(pt_);
//4.啟動系統執行緒pt_->start()
//5.自定義執行緒 訊號->槽函式工作
//6.關閉執行緒pt_->quit()  pt_->wait()

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

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

 void MainWindow::init()
 {
     //注意:構造的時候不能定義父物件
     //子執行緒中不能處理ui視窗
     ptimer_=new QTimer(this);

     //1.構造自定義,構造系統,關聯自定義和系統的,觸發工作執行緒
     pmyt_ =new MyThread;
     pt_=new QThread(this);
     pmyt_->moveToThread(pt_);
     connect(this,&MainWindow::singalWorking,pmyt_,&MyThread::doMyWork);

     //2.ui-> 按鈕 start stop
     connect(ui->start_btn,&QPushButton::clicked,this,&MainWindow::slotStart);
     connect(ui->stop_btn,&QPushButton::clicked,this,&MainWindow::slotStop);
     // 定時器
     connect(ptimer_,&QTimer::timeout,this,&MainWindow::slotTimeout);
     //3.析構掉執行緒
     connect(this,&MainWindow::destroyed,this,&MainWindow::slotCloseThread);
     //列印當前的thread
     qDebug() <<"主執行緒號 Thread:"<<QThread::currentThread();
 }
 //啟動子執行緒,start(),子執行緒工作函式還沒開始執行,要觸發訊號就可以了。
 void MainWindow::slotStart()
 {
     if(ptimer_->isActive()==true)
     {
         return;
     }
     ptimer_->start(500);

     if(pt_->isRunning()==true)
     {
         return;
     }
     if(pt_->isRunning())
     {
         return ;
     }
     // 啟動執行緒 但沒有啟動執行緒處理函式
     pt_->start();
     pmyt_->setFlag(false);
     //觸發訊號才讓子執行緒工作函式開始工作
     emit singalWorking();

 }
 void MainWindow::slotStop()
 {
     ptimer_->stop();
     if(pt_->isRunning()==false)
     {
         return;
     }
      pmyt_->setFlag(true);
      pt_->quit();
      pt_->wait();
 }

 //關閉執行緒
 void MainWindow::slotCloseThread()
 {
     if(pt_->isRunning()==false)
     {
         return;
     }
      pmyt_->setFlag(true);
      pt_->quit();
      pt_->wait();
 }
 //定時器
 void MainWindow::slotTimeout()
 {
     static int i=0;
     ui->lcdNumber->display(i++);
 }