1.简介
QThread是Qt中用于处理多线程的类。它允许开发者在应用程序中创建独立的线程,这些线程可以并发执行,从而提高程序的性能和响应能力。而线程是操作系统中的基本执行单元,每个线程都有自己的栈空间,用于存储本地变量和函数调用的上下文。QThread作为Qt中的线程类,提供了对线程管理的支持。
主要特点:
- 跨平台性:Qt应用程序可以在不同的平台上运行,QThread可以在所有支持Qt的平台上使用,增强了应用程序的可移植性。
- 信号与槽机制:QThread继承自QObject,支持Qt的信号与槽机制,使得线程间的通信更加安全和方便。
- 线程安全性:Qt库本身是线程安全的,因此可以在多个线程中同时使用Qt类和对象,保证了数据的一致性和正确性。
- 事件循环:QThread为每个线程自动创建一个事件循环,并在该循环中执行线程所需的任务,使得线程的使用更加高效和灵活。
Qt的线程类QThread提供了常用方法,需要集成后使用。提供了线程入口函数run,这是一个受保护的虚函数,需要重新实现自定义代码。下面创建一个小的场景,线程的开始与停止受到主界面的按钮控制,一旦线程开始运行,则发出超时信号(时间间隔对外提供方法设置),主线程接收超时信号并进行处理,让LCD显示部件加1。
2.实现步骤
- 1.创建主界面类,并设计ui界面如下:
- 2.新建c++类继承自QThread
- 新建类继承时通常选择继承自QWidget,等待创建好之后在修改。添加QThread头文件;修改从哪个类继承,在代码部分我已做了标注。
- 重新run函数,run函数重写成每隔固定的时间间隔发出一个信号。
- 对外提供一个可以修改这个时间间隔的方法
- 3.主线程中创建子线程类对象
- 使用按钮控制子线程的开始与暂停
- 接收子线程的信号,并进行处理,让LCD每次收到信号加1。
注:connect函数第五个参数,采用Qt::BlockingQueuedConnection参数让子线程阻塞,直到主线程处理完毕,也就是同步处理,区别于Qt::QueuedConnection参数等控制权回到主线程在执行处理。 实际应用中应结合具体的应用需求选择合适的参数。
3.效果
与代码部分一致,每2秒发送一次信号
4.代码
main
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h主线程
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void doProcessTimeOut();
void on_startBtn_clicked();
void on_stopBtn_clicked();
private:
Ui::Widget *ui;
myThread *thr;
int index;
};
#endif // WIDGET_H
widget.cpp主线程
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
index = 0;
thr = new myThread(this);
connect(thr,SIGNAL(signalTimeOut()),this,SLOT(doProcessTimeOut()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::doProcessTimeOut()
{
index++;
if(index==101)
{
index=0;
}
ui->lcdNumber->display(index);
}
void Widget::on_startBtn_clicked()
{
//可修改时间间隔
thr->setTimeSecend(2);//修改每两秒加1
thr->start();
}
void Widget::on_stopBtn_clicked()
{
thr->terminate();
}
mythread.h子线程
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QWidget>
#include <QThread>//添加头文件
class myThread : public QThread//继承修改1
{
Q_OBJECT
public:
explicit myThread(QWidget *parent = nullptr);//构造函数参数,可不改
void setTimeSecend(int sec);
protected:
void run();
signals:
signalTimeOut();
private:
int time_sec;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
myThread::myThread(QWidget *parent) : QThread(parent)//继承修改2
{
time_sec = 1;
}
void myThread::run()
{
while (1) {
sleep(time_sec);
emit signalTimeOut();
}
}
void myThread::setTimeSecend(int sec)
{
time_sec = sec;
}
5.传送门
END |
🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。