与前篇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++);
}