2023-02-05 QT 线程实现和计时器使用

第一种方式创建线程工作,继承QThread,实现run纯虚函数

1、需要创建一个继承QThread的类
2、在类里面实现run() 纯虚函数
3、实例化这个类,调用父类函数start(),回调函数run()开始执行。
4、还可以在这个类写一个信号,信号不需要实现,信号也可以带参数,如果带参数,需要槽函数匹配一样类型参数接收,这个不需要赋值,槽函数参数自动接收。


实例

界面

通过绘制一个lcd计数器,和一个按钮,点击按钮实现,通过计时器每隔500ms触发一次timeout信号,在构造函数,使用timeout信号和计数器加一绑定一起,每隔500ms,计数器就加一,但是如果,timer启动之后有一个耗时的工作,那么只能等耗时的工作完成之后,才会触发timeout信号,导致计时器不能同时工作,所以需要一个开启一个线程,把耗时工作,放入线程里面。这样界面的lcd就可以正常启动,界面也不会卡死。

二话不说上代码

自定义线程头文件

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class myThread : public QThread
{
    Q_OBJECT
public:
    explicit myThread(QThread *parent = nullptr);
private:

protected:
    //继承QThread run 纯虚函数 纯虚函数一定要写实现
    //线程内容在run函数里面写
    //自定义线程,回调函数,当自定义线程 myThread.start(),会进入到这里
    void run() override;

signals:
    //信号,可以写一个信号,当自定义线程里面内容实现完成,发生信号通知线程内容已完成。
    void done();
};

#endif // MYTHREAD_H

自定义线程.cpp文件

#include "mythread.h"

myThread::myThread(QThread *parent) : QThread(parent)
{

}

void myThread::run()
{
    //耗时工作
    //等耗时工作完成,emit signals ,通知外部,耗时工作已完成
    sleep(5);
    emit done();
}

Widget 头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTimer>
#include<QThread>
#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 on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QTimer *timer;
    myThread *m_T;

};
#endif // WIDGET_H

Widget .cpp文件

#include "widget.h"
#include "ui_widget.h"
#include<QElapsedTimer>
#include<QtDebug>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化计时器
    timer = new QTimer();
    //实例化线程
    m_T= new myThread();

    connect(timer,&QTimer::timeout,this,[=](){
        static int num =0;
        ui->lcdNumber->display(num++);
    });
    connect(m_T,&myThread::done,this,[=](){
         qDebug()<<"线程工作完成";
    });
}

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


void Widget::on_pushButton_clicked()
{
    //判断计时器是否是处于活动
    //以免计时器重复运行。
    if(true==timer->isActive())
    {
        return;
    }
   timer->start(500);


   //QT 计时函数 QElapsedTimer
   //time.start() 开始计时
   //time.elapsed() 计时结果
//   QElapsedTimer time;
//   time.start();
//   QThread::sleep(3);
//   qDebug()<<time.elapsed();

    //线程开始,默认线程优先级,参数(线程优先级)
   //通过debug可以得到线程运行,通过得到时间函数,得不出线程工作时间。
   QElapsedTimer time;
   time.start();
   m_T->start();
   qDebug()<<time.elapsed();


}

第二种创建线程工作,调用工作类(继承QObject)对象的moveToThread方法

1、先创建工作类,在工作类里面写一个槽函数,一个信号(主要是线程执行槽函数通知外部)

#ifndef WORK_H
#define WORK_H

#include <QObject>
#include<QDebug>
class work : public QObject
{
    Q_OBJECT
public:
    explicit work(QObject *parent = nullptr);
public slots:
    //线程工作内容
    void  dowork(int parameter);
signals:
    //线程完成工作内容发送的信号
    void resultReady(const int result);
};

#endif // WORK_H

#include "work.h"

work::work(QObject *parent)
    : QObject{parent}
{

}

void work::dowork(int parameter)
{
    //耗时工作
    qDebug()<<"work start";
    for(int i =0;i<1000;++i)
    {
        ++parameter;

    }

    //耗时工作完成发出完成信号
    emit resultReady(parameter);
}


2、创建一个触发或者说是连接线程和工作类的类,在类里面声明一个QThred的全局变量。实例化一个工作类对象,调用这个对象的moveToThread类,传入QThread变量。
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QObject>
#include<QThread>
#include<QDebug>
#include"work.h"

class Controller : public QObject
{
    Q_OBJECT
    QThread workerThread;
public:
    explicit Controller(QObject *parent = nullptr);
    ~Controller()override;
public slots:
    //处理线程执行的结果
    static void handleResults(int result);
signals:
    //发送信号,触发线程工作
    void operate1(const int);
};

#endif // CONTROLLER_H

通过触发信号和工作的槽函数连接起来,启动线程,触发信号,线程就执行了。

#include "controller.h"

Controller::Controller(QObject *parent)
    : QObject{parent}
{
    
    //工作类实例化
    auto *worker = new work;
    //将worker对象的事件循环全部交由workerThread线程
    worker->moveToThread(&workerThread);
    //触发信号,开始工作。
    connect(this,&Controller::operate1,worker,&work::dowork);
    //线程执行完成发出信号,接收信号执行下一个动作;
    connect(worker,&work::resultReady,this,&Controller::handleResults);
    //线程结束时候销毁
    connect(&workerThread,&QThread::finished,worker,&QThread::deleteLater);

    //启动线程
    workerThread.start();

    //触发线程工作
    emit operate1(0);

}

Controller::~Controller()
{
    workerThread.quit();
    workerThread.wait();
}

void Controller::handleResults(int result)
{

    qDebug() << "receive the resultReady signal" ;
    qDebug() << "\tCurrent thread ID: " << QThread::currentThreadId() << '\n' ;
    qDebug() << "\tThe last result is: " << result ;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容