进阶2_1:QT5多线程与定时器共生死

发布于:2025-05-19 ⋅ 阅读:(18) ⋅ 点赞:(0)

1、在widget.ui中使用 LCD Number控件

注意:若 LCD 控件不是多线程,LCD控件则会瞬间自增到最大的数值,如上图,说明两者都是多线程处理

2、实现方式

1、创建 LCD 控件并修改为 LCD1

2、创建任务类 mytask. h,对任务类添加信号、槽、任务的全局变量

#ifndef MYTASK_H
#define MYTASK_H

#include <QObject>

class MyTask : public QObject
{
    Q_OBJECT
public:
    explicit MyTask (QObject *parent = nullptr);

//子线程发送信号
signals:
    void task2_signal (int i);

//子线程接收的槽函数
public slots:
    void StartTimerSlots ();

private:
    int i=0;//设置为全局变量后,必须为置为0,否则就会出现任意值
    QString current_date=nullptr;//可以不用赋值,默认被置为NULL
};

#endif // MYTASK_H

3、在用户界面 widget. h 添加全局变量(线程变量、任务变量)

#ifndef WIDGET_H
#define WIDGET_H

#include <QThread>
#include <QWidget>
#include "mytask.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void TasksInit();//任务初始化


private:
    Ui::Widget *ui;
    MyTask *task2; //任务2
    QThread *mythread;//任务2的线程

};
#endif // WIDGET_H

4、在 mytask. cpp 中实现 void StartTimerSlots () 这个函数

#include "mytask.h"
#include <QDebug>
#include <unistd.h>

MyTask::MyTask(QObject *parent) : QObject(parent)
{

}

//任务的槽函数
void MyTask::StartTimerSlots()
{
	//创建定时器对象
    QTimer *timer = new QTimer;
    //定时器超时(每1s)后,自动加1
    connect(timer, &QTimer::timeout, this, [=]{
        qDebug() << "子线程定时器触发" << i;
        emit task2_signal(i++);
    });
    timer->start(1000);
}

5、在 wideget. cpp 中

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTimer>
#include "mytask.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    TasksInit();
}

Widget::~Widget()
{
    delete ui;
}

/*
功能:对 TCP服务端 进行多线程处理
参数:无参
返回值:无
*/
void Widget::TasksInit()
{
    MyTask *task2 = new MyTask;
    QThread *mythread = new QThread;
    task2->moveToThread(mythread);
    mythread->start();

    //创建定时器的开启和关闭
    connect(mythread, &QThread::started,task2,&MyTask::StartTimerSlots);  // 启动信号
    connect(mythread, &QThread::finished,task2,&QObject::deleteLater);    // 停止信号
    connect(mythread, &QThread::finished,mythread,&QObject::deleteLater);    // 停止信号

    connect(task2,&MyTask::task2_signal,this,[=](int i){
        ui->LCD1->display(i);
    },Qt::QueuedConnection);
    connect(this, &QObject::destroyed, this, [=] {
        delete task2;
        mythread->quit();
        mythread->wait();
        mythread->deleteLater();
    });
}

6、解释 wideget. cpp 中执行的步骤

MyTask *task2 = new MyTask; //创建任务对象
QThread *mythread = new QThread; //创建线程对象 
task2->moveToThread(mythread);//将任务放置到线程中
mythread->start();//开启线程
//等待线程开启,执行任务中的槽函数
connect(mythread, &QThread::started,task2,&MyTask::StartTimerSlots);
//等待线程结束,就销毁任务、线程
connect(mythread, &QThread::finished,task2,&QObject::deleteLater);    
connect(mythread, &QThread::finished,mythread,&QObject::deleteLater); 
//等待任务发送信号,用户界面this,接收信号发来的参数i
connect(task2,&MyTask::task2_signal,this,[=](int i){
            ui->LCD1->display(i);//数据i++用于显示LCD
        });
//销毁任务,线程(先销毁任务,在销毁线程)
connect(this, &QObject::destroyed, this, [=] {
    delete task2;
    mythread->quit();
    mythread->wait();
    mythread->deleteLater();
});
注意:task2的销毁事件先于mythread销毁事件
效果:通过上述,实现了,在多线程中使用定时器,定时器与线程同时开启、关闭


网站公告

今日签到

点亮在社区的每一天
去签到