开发者

Qt两种定时器使用实现方式

开发者 https://www.devze.com 2024-01-31 10:34 出处:网络 作者: 锅巴大王
目录QT 中使用定时器,有两种方式:QTimer:QTimerEvent:下面举一个案例:看看实际项目中怎么用附:QTimer的替代方案总结 QT 中使用定时器,有两种方式:
目录
  • QT 中使用定时器,有两种方式:
  • QTimer:
  • QTimerEvent:
  • 下面举一个案例:看看实际项目中怎么用
  • 附:QTimer的替代方案
  • 总结 

QT 中使用定时器,有两种方式:

  • 定时器类:QTimer
  • 定时器事件:QEvent::Timer,对应的子类是 QTimerEvent

简单讲一下两种用法:

QTimer:

QTimer 需要创建QTimer对象

  •   然后需要给定时器绑定 定时器超时的槽函数,也就是时间到了,该做什么
  •  一般用按钮控制定时器,所以跟按钮关联的槽函数一般里面有start,stop就是控制定时器的
  •  这样通过按钮点击之后,调用里面Qtimer的start,因为外面绑定了定时器超时槽函数,所以
  • &androidnbsp;定时器到时间了就会调用超时槽函数,完成业务逻辑

QTimerEvent:

  •  需要重写void QObject::timerEvent(QTimerEvent *event)
  •  当定时时间到的时候会自动调用timerEvent
  •  用timerId可以获取哪个定时器的id
  •  startTimer()可以设置定时器时间间隔 ms
  •  killTimer停止定时器

对于 QTimerEvent不用重写定时器超时函数并且再手动绑定,QTimerEvent他会自动调用timerEvent,该函数将自动在使用startTimer函数启动的定时器到期时被调用,所以只需要重写这个就行

下面举一个案例:看看实际项目中怎么用

Qt两种定时器使用实现方式

这有一个定时器任务的页面,无ui的,手撕代码去写

.h

#ifndef TIMEREVENT_H
#define TIMEREVENT_H

#include <QWidget>
#include <QTimer>
#include <QTimerEvent>
#include <QLabel>

class TimerEvent : public QWidget
{
    Q_OBJECT
public:
    explicit TimerEvent(QWidget *parent = nullptr);
private slots:
    void startclick();
    void pauseclick();
    void restartclick();

    //用QTimer,定时器超时的槽函数
    void timerout1();
    void timerout2();
private:
    QLabel* lab1;
    QLabel* lab2;
    int id1;
    int id2;
    //QTimer
    QTimer *tm1;
    QTimer *tm2;
private:
    //QTimerEvent
    void timerEvent(QTimerEvent *event);
signals:

};

#endif // TIMEREVENT_H

.cpp

#include "timerevent.h"
#include <QvboxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QDebug>

//  定时器事件
/*
 * 做定时器有两种方式,一种QTimer类,一种是QEvent的Timer事件 ,用到的子类是QTimerEvent
 * 用两种都去实现一下
 * 1.QTimerEvent
 * 需要重写void QObject::timerEvent(QTimerEvent *event)
 * 当定时时间到的时候会自动调用timerEvent
 * 用timerid可以获取哪个定时器的id
 * startTimer()可以设置定时器时间间隔 ms
 * killTimer停止定时器
 *
 * 2.
 *QTimer 需要创建QTimer对象
 * 然后需要给定时器绑定 定时器超时的槽函数
 * 一般在按钮里面有start,stop就是控制定时器的
 * 这样通过按钮点击之后,调用里面Qtimer的start,因为外面绑定了定时器超时槽函数,RbvpMs所以
 * 定时器到时间了就会调用超时槽函数
 * 对于 QTimerEvent不用重写超时函数并且去手动绑定,他会自动调用timerEvent,只需要重写这个就行
 * */
TimerEvent::TimerEvent(QWidget *parent) : QWidget(parent)
{
    //垂直布局
    QVBoxLayout *vblayout = new QVBoxLayout(this);
    vblayout->setSpacing(0);
    vblayout->setContentsMargins(0,0,0,0);

    //
    QLabel *ql = new QLabel(this);
    ql->setText("定时器事件");
    ql->setFixedHeight(50);
    ql->setAlignment(Qt::AlignCenter);
    ql->setFrameShape(QFrame::Box);
    ql->setStyleSheet("color:green;font:25px;background-color:rgb(0,233,233);border-radius:10px;"
                      );
    vblayout->addwidget(ql);

    //第一个标签
    lab1 = new QLabel(this);http://www.devze.com
    lab1->setFixedSize(95,95);
    lab1->setFrameShape(QFrame::Box);
    lab1->setStyleSheet("background-color:yellow");
    vblayout->addWidget(lab1);
    //第二个标签
    lab2 = new QLabel(this);
    lab2->setFixedSize(95,95);
    lab2->setFrameShape(QFrame::Box);
    lab2->setStyleSheet("background-color:purple");
    vblayout->addWidget(lab2);
    //三个按钮
    QPushButton* start= new QPushButton(this);
    start->setText("开始");
    QPushButton* pause= new QPushButton(this);
    pause->setText("暂停");
    QPushButton* restart= new QPushButton(this);
    restart->setText("复位");
    this->setStyleSheet(R"(
          android              QPushButton{
                        font-size:20px;
                        })");
    //水平布局
    QHBoxLayout *hb = new QHBoxLayout(this);
    hb->setSpacing(0);
    hb->setContentsMargins(0,0,0,0);

    hb->addWidget(start);
    hb->addWidget(pause);
    hb->addWidget(restart);
    vblayout->addLayout(hb);

    //按键的信号槽
    connect(start,&QPushButton::clicked,this,&TimerEvent::startclick);
    connect(pause,&QPushButton::clicked,this,&TimerEvent::pauseclick);
    connect(restart,&QPushButton::clicked,this,&TimerEvent::restartclick);

    //Qtimer绑定的信号槽
    tm1 = new QTimer(this);
    tm2 = new QTimer(this);
    connect(tm1,&QTimer::timeout,this,&TimerEvent::timerout1);
    connect(tm2,&QTimer::timeout,this,&TimerEvent::timerout2);
}

void TimerEvent::startclick()
{
#ifdef USR_TIMER_EVENT
    qDebug()<<"use timerevent";
    id1=startTimer(10);
    id2=startTimer(20);
#else
    qDebug()<<"use Qtimer";
    tm1->start(10);
    tm2->start(20);
#endif
}

void TimerEvent::pauseclick()
{
#ifdef USR_TIMER_EVENT
    qDebug()<<"use timerevent";
    killTimer(id1);
    killTimer(id2);
#else
    qDebug()<<"use Qtimer";
    tm1->stop();
    tm2->stop();
#endif
}

void TimerEvent::restartclick()
{
    lab1->move(0,lab1->y());
    lab2->move(0,lab2->y());
}
//Qtimer
void TimerEvent::timerout1()
{
    lab1->move(lab1->x()+5,lab1->y());
    if(lab1->x()>=this->width()){
        lab1->move(0,lab1->y());
    }

}

void TimerEvent::timerout2()
{
    lab2->move(lab2->x()+5,lab2->y());
    if(lab2->x()>=this->width()){
        lab2->move(0,lab2->y());
    }
}
//timerevent
void TimerEvent::timerEvent(QTimerEvent *event)
{
    //当定时器时间到了,看是哪个定时器
    if(event->timerId()==id1){
        lab1->move(lab1->x()+5,lab1->y());
        if(lab1->x()>=this->width()){
            lab1->move(0,lab1->y());
        }
    }
    if(event->timerId()==id2){
        lab2->move(lab2->x()+5,lab2->y());
        if(lab2->x()>=this->width()){
            lab2->move(0,lab2->y());
        }
    }
}

附:QTimer的替代方案

第 3点 总的来说,QTimer是最优的定时器方案,有现成的封装的很完善的功能,就用 QTimer就行。

使用QTimer的另一种选择是为你的对象调用QO编程bject::startTimer(),并在你的类(必须继承QObject)中重新实现QObject::timerEvent()事件处理程序。缺点是timerEvent()不支持诸如单触发定时器或信号之类的高级特性。

另一个替代方法是QBasicTimer。这通常比直接使用QObject::startTimer()要简单得多。

  • 替代方法一:
class MyObject : public QObject
  {
      Q_OBJECT

  public:
      MyObject(QObject *parent = nullptr);

  protected:
      void timerEvent(QTimerEvent *event) override;
  };

  MyObject::MyObject(QObject *parent)
      : QObject(parent)
  {
      startTimer(50);     // 50-millisecond timer
      startTimer(1000);   // 1-second timer
      startTimer(60000);  // 1-minute timer

      using namespace std::chrono;
      startTimer(milliseconds(50));
      startTimer(seconds(1));
      startTimer(minutes(1));

      // since C++14 we can use std::chrono::duration literals, e.g.:
      startTimer(100ms);
      startTimer(5s);
      startTimer(2min);
      startTimer(1h);
  }

  void MyObject::timerEvent(QTimerEvent *event)
  {
      qDebug() << "Timer ID:" << event->timerId();
  }

一些操作系统会限制可能使用的定时器的数目。Qt试图绕过这些限制。

总结 

到此这篇关于Qt两种定时器使用的文章就介绍到这了,更多相关Qt定时器使用内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消