使用Qt中自带的线程类QThread时
1、需要定义一个子类继承自QThread
2、重写run()方法,在run方法中编写业务逻辑
3、子类支持信号槽
4、子类的构造函数的执行是在主线程进行的,而run方法的执行是在子线程中进行的
常用方法
静态方法
获取线程id
可以得到当前线程的id
[static noexcept] Qt::HANDLE QThread::currentThreadId()
线程睡眠
void msleep(unsigned long msecs)//单位毫秒
void sleep(unsigned long secs)//单位秒
(since 6.6) void sleep(std::chrono::nanoseconds nsecs)//单位纳秒
void usleep(unsigned long usecs)//单位微秒
公共方法
判断线程是否执行完毕
bool QThread::isFinished() const
判断线程是否正在运行
bool QThread::isRunning() const
判断线程是否被请求中断了
bool QThread::isInterruptionRequested() const
可以在子线程中的run函数中通过这个函数获知是否需要中断退出了
发出中断请求
调用这个方法可以向线程发起中断请求,调用后:isInterruptionRequested()会返回true
void QThread::requestInterruption()
等待线程
是一个阻塞函数,调用他来确保线程已经执行完毕
bool QThread::wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))
通常使用其默认参数,如果线程一直不执行完毕,那么该函数的调用者将会一直被阻塞,直到线程执行完毕
公有槽函数
启动线程
通常我们调用该函数来启动线程
[slot] void QThread::start(QThread::Priority priority = InheritPriority)
终止线程
通常我们调用该方法强制终止一个线程,但不建议
[slot] void QThread::terminate()
常用信号
线程开始执行时会发出started信号
线程执行完毕退出后会发出finished信号
这两个都是私有信号,只能被连接,不能用来主动发射
void finished()
void started()
举例:
点击开启按钮,会开启一个线程
点击关闭按钮,会发出中断请求,使得线程退出
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QThread>
#include<QPushButton>
class Thread01:public QThread
{
Q_OBJECT
public:
Thread01(int num):m_num(num)
{
//构造函数的调用是在主线程
//可以打印线程id,查看区别
qDebug()<<"线程id:"<<QThread::currentThreadId();
}
~Thread01()=default;
protected:
//重写run方法
void run() override
{
//run函数在子线程中运行
qDebug()<<"线程id:"<<QThread::currentThreadId();
while(1)
{
//如果请求中断的话就退出
if(isInterruptionRequested())
{
return;
}
//循环自增,然后打印
qDebug()<<m_num++;
}
}
private:
int m_num=0;
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr) : QWidget(parent)
{
resize(300,300);
QPushButton* btn=new QPushButton("开启线程",this);
btn->setGeometry(10,10,100,100);
QPushButton* btn2=new QPushButton("退出线程",this);
btn2->setGeometry(10,btn->geometry().bottom()+10,100,100);
//创建线程
Thread01* th=new Thread01(100);//从100开始自增
connect(btn,&QPushButton::clicked,this,[=](){
//开启线程
if(!th->isRunning())
{
th->start();
}
});
connect(btn2,&QPushButton::clicked,this,[=](){
//线程正在执行的话
if(th->isRunning())
{
//中断线程
th->requestInterruption();
}
//使用wait方法确保线程退出了
if(th->wait())
{
qDebug()<<"线程退出了";
}
});
}
~Widget()=default;
private:
};
#endif // WIDGET_H
学习链接:https://github.com/0voice