文章目录
- 源文件类
- 实现方法 1
- 实现方法 2
- 总结
源文件类
widget
类为主线程,mythread
为待创建的子线程类
点击按钮线程开始执行(针对方法一,方法二忽略图形界面)
实现方法 1
widget.h
#include <QWidget>
#include <QThread>
#include "mythread.h"
class Widget : public QWidget
{
Q_OBJECT
public:
QThread * thread; // 子线程
mythread * mth; // 子线程模块
void closeThread(); // 关闭子线程
};
注: 上面省略掉无关代码
widget.cpp
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 1. 自定义线程模块 设置该线程需要完成的任务
mth = new mythread;
// 2. 创建子线程 (理解为线程管理者)
thread = new QThread(this);
// 3. 将准备好的线程类和子线程关联
mth->moveToThread(thread);
// 4. 启动子线程,但是,并没有启动线程处理函数
thread->start();
// 5. 线程处理函数需要通过 信号-槽 调用
connect(ui->pushButton, &QPushButton::pressed, mth, &mythread::printInfo);
// 6. 关闭线程
connect(this, &Widget::destroyed, this, &Widget::closeThread);
}
// 关闭线程函数
void Widget::closeThread()
{
thread->quit(); // 退出子线程
thread->wait(); // 回收线程资源
delete mth; // 释放线程模块内存
}
mythread.cpp
#include "mythread.h"
#include <QDebug>
mythread::mythread(QObject *parent) : QObject(parent)
{}
void mythread::printInfo()
{
qDebug()<<"线程正在执行..."<<endl;
// if(true)
// exit(1);
}
实现方法 2
这里忽略掉ui界面
widget.h
#include <QWidget>
#include "mythread.h"
class Widget : public QWidget
{
Q_OBJECT
public:
mythread * thread; // 声明一个线程类对象
void closeThread(); // 关闭线程
};
注: 省略掉无关代码
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QThread>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 1. 创建线程对象
thread = new mythread(this);
// 2. 会间接调用mythread::run()线程处理函数开始处理数据
thread->start();
// 3. 线程处理函数需要通过 信号-槽 调用
connect(thread, &mythread::isDone,this,&Widget::closeThread);
}
// 关闭线程函数
void Widget::closeThread()
{
thread->quit(); // 退出子线程
thread->wait(); // 回收线程资源
delete thread; // 释放线程模块的内存
}
mythread.h
#include <QThread>
class mythread : public QThread
{
Q_OBJECT
protected:
//QThread的虚函数,也是线程处理函数
//不能直接调用,通过start()间接调用,因为这是个protected函数
void run();
signals:
void isDone(); // 线程功能执行完毕
};
mythread.cpp
#include "mythread.h"
#include <QDebug>
mythread::mythread(QObject *parent) : QThread(parent)
{}
void mythread::run()
{
for(int i = 0; i < 100000000; i++)
qDebug()<<"线程正在执行..."<<endl;
qDebug()<<"数据处理完毕,我要发出退出信号的"<<endl;
emit isDone(); // 发送执行完毕信号
}
注意: mythread
类的继承对象时QThread
总结
- 注意第一个方法里面线程继承的是
QObject
类,而方法二里面继承的类是QThread
- 方法一种
thread->start()
会启动线程但不会启动线程处理函数,方法二中会直接调用mythread::run()
,且run
就是线程处理函数 - 方法一中线程处理函数可以自定义,方法二中线程处理函数固定是
run()
不能额外自定义 - 方法二只需创建线程对象,然后start调用线程函数,最后关闭线程,操作比较简单;方法二需要创建两个对象然后关联,调用线程处理函数需要信号和槽触发,实现比较复杂。
- 方法一是4.7版本之前的使用方法,方法二是4.7之后的使用方法。