Qt两种定时器使用实现方式
作者:锅巴大王
这篇文章主要给大家介绍了关于Qt两种定时器使用实现方式的相关资料,Qt中的定时器类是QTimer,QTimer不是一个可见的界面组件,文中通过代码介绍的非常详细,需要的朋友可以参考下
QT 中使用定时器,有两种方式:
- 定时器类:
QTimer - 定时器事件:
QEvent::Timer,对应的子类是QTimerEvent
简单讲一下两种用法:
QTimer:
QTimer 需要创建QTimer对象
- 然后需要给定时器绑定 定时器超时的槽函数,也就是时间到了,该做什么
- 一般用按钮控制定时器,所以跟按钮关联的槽函数一般里面有start,stop就是控制定时器的
- 这样通过按钮点击之后,调用里面Qtimer的start,因为外面绑定了定时器超时槽函数,所以
- 定时器到时间了就会调用超时槽函数,完成业务逻辑
QTimerEvent:
- 需要重写void QObject::timerEvent(QTimerEvent *event)
- 当定时时间到的时候会自动调用timerEvent
- 用timerId可以获取哪个定时器的id
- startTimer()可以设置定时器时间间隔 ms
- killTimer停止定时器
对于 QTimerEvent不用重写定时器超时函数并且再手动绑定,QTimerEvent他会自动调用timerEvent,该函数将自动在使用startTimer函数启动的定时器到期时被调用,所以只需要重写这个就行
下面举一个案例:看看实际项目中怎么用

这有一个定时器任务的页面,无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,因为外面绑定了定时器超时槽函数,所以
* 定时器到时间了就会调用超时槽函数
* 对于 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);
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"(
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的另一种选择是为你的对象调用QObject::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定时器使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
