特点:使用相对而言复杂,但是比较灵活
思路:
项目实例:
源码交流:
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
#include <QDebug>
class MyThread : public QObject
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void MyTimeout();//线程处理函数
void setFlage(bool flag = true); //设置标志位,何时关闭子线程
signals:
void MySignal();
public slots:
protected:
bool isStop;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
MyThread::MyThread(QObject *parent) : QObject(parent)
{
isStop = false;
}
//线程处理函数
void MyThread::MyTimeout()
{
while(false == isStop)
{
QThread::sleep(1);
emit MySignal(); //每隔一秒发射一次信号
qDebug()<<"子线程ID:"<<QThread::currentThread(); //显示当前线程的数值
if(true == isStop)
{
break;
}
}
}
void MyThread::setFlage(bool flag)
{
isStop = flag;
}
mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include "mythread.h"
#include <QThread>
#include <QDebug>
namespace Ui {
class MyWidget;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
void dealMySignal();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void dealClose();
signals:
void startMyThread(); //启动子线程的信号
private:
Ui::MyWidget *ui;
MyThread *myThread;
QThread *thread;
};
#endif // MYWIDGET_H
mywidget.cpp
#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
//创建线程对象,不能够指定父对象
myThread = new MyThread;
//创建子线程对象
thread = new QThread(this);
//把子线程(对象)添加到自定义的线程类(对象)中
myThread->moveToThread(thread);
connect(myThread, &MyThread::MySignal, this, &MyWidget::dealMySignal);
qDebug()<<"主线程ID:"<<QThread::currentThread(); //显示当前线程的数值
connect(this, &MyWidget::startMyThread, myThread, &MyThread::MyTimeout);
connect(this, &MyWidget::destroyed, this, &MyWidget::dealClose);
//线程处理函数内部,不允许操作图形界面
//connect()第五个参数的作用, 连接方式: 默认, 队列,直接
//多线程才有含义
//默认的时候
//如果是多线程,默认使用队列
//如果是单线程,默认使用直接方式
//队列:槽函数所在线程和接受(信号)者一样
//直接:槽函数所在线程和发送(信号)者一样
}
MyWidget::~MyWidget()
{
delete ui;
}
//处理收到的线程的信号, 作出相应动作
void MyWidget::dealMySignal()
{
static int i = 0;
i++;
ui->lcdNumber->display(i);
}
//启动子线程
void MyWidget::on_pushButton_clicked()
{
if(thread->isRunning() == true) //这个判断个什么鬼?
{
return;
}
//启动子线程,但没有启动线程处理函数
thread->start();
myThread->setFlage(false);
//**************************************************
//不能够直接调用该线程处理函数
//不然的话,都会导致线程处理函数和主线程是在同一个线程
// myThread->MyTimeout();
//**************************************************
//只能够通过 signal - slot 来调用线程处理函数
emit startMyThread();
}
void MyWidget::on_pushButton_2_clicked()
{
if(thread->isRunning() == false)
{
return;
}
myThread->setFlage(true);
thread->quit();
thread->wait();
}
void MyWidget::dealClose()
{
on_pushButton_2_clicked();
delete myThread; //因为没有指定父对象,所以不释放会溢出,但是没有设么大问题
}