QT應用(7)-多執行緒-QT4.7以後的版本
阿新 • • 發佈:2021-01-18
技術標籤: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.自定義執行緒 訊號->槽函式工作
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++);
}