Qt兩種定時(shí)器使用實(shí)現(xiàn)方式
QT 中使用定時(shí)器,有兩種方式:
- 定時(shí)器類:
QTimer - 定時(shí)器事件:
QEvent::Timer,對(duì)應(yīng)的子類是QTimerEvent
簡(jiǎn)單講一下兩種用法:
QTimer:
QTimer 需要?jiǎng)?chuàng)建QTimer對(duì)象
- 然后需要給定時(shí)器綁定 定時(shí)器超時(shí)的槽函數(shù),也就是時(shí)間到了,該做什么
- 一般用按鈕控制定時(shí)器,所以跟按鈕關(guān)聯(lián)的槽函數(shù)一般里面有start,stop就是控制定時(shí)器的
- 這樣通過按鈕點(diǎn)擊之后,調(diào)用里面Qtimer的start,因?yàn)橥饷娼壎硕〞r(shí)器超時(shí)槽函數(shù),所以
- 定時(shí)器到時(shí)間了就會(huì)調(diào)用超時(shí)槽函數(shù),完成業(yè)務(wù)邏輯
QTimerEvent:
- 需要重寫void QObject::timerEvent(QTimerEvent *event)
- 當(dāng)定時(shí)時(shí)間到的時(shí)候會(huì)自動(dòng)調(diào)用timerEvent
- 用timerId可以獲取哪個(gè)定時(shí)器的id
- startTimer()可以設(shè)置定時(shí)器時(shí)間間隔 ms
- killTimer停止定時(shí)器
對(duì)于 QTimerEvent不用重寫定時(shí)器超時(shí)函數(shù)并且再手動(dòng)綁定,QTimerEvent他會(huì)自動(dòng)調(diào)用timerEvent,該函數(shù)將自動(dòng)在使用startTimer函數(shù)啟動(dòng)的定時(shí)器到期時(shí)被調(diào)用,所以只需要重寫這個(gè)就行
下面舉一個(gè)案例:看看實(shí)際項(xiàng)目中怎么用

這有一個(gè)定時(shí)器任務(wù)的頁面,無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,定時(shí)器超時(shí)的槽函數(shù)
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>
// 定時(shí)器事件
/*
* 做定時(shí)器有兩種方式,一種QTimer類,一種是QEvent的Timer事件 ,用到的子類是QTimerEvent
* 用兩種都去實(shí)現(xiàn)一下
* 1.QTimerEvent
* 需要重寫void QObject::timerEvent(QTimerEvent *event)
* 當(dāng)定時(shí)時(shí)間到的時(shí)候會(huì)自動(dòng)調(diào)用timerEvent
* 用timerid可以獲取哪個(gè)定時(shí)器的id
* startTimer()可以設(shè)置定時(shí)器時(shí)間間隔 ms
* killTimer停止定時(shí)器
*
* 2.
*QTimer 需要?jiǎng)?chuàng)建QTimer對(duì)象
* 然后需要給定時(shí)器綁定 定時(shí)器超時(shí)的槽函數(shù)
* 一般在按鈕里面有start,stop就是控制定時(shí)器的
* 這樣通過按鈕點(diǎn)擊之后,調(diào)用里面Qtimer的start,因?yàn)橥饷娼壎硕〞r(shí)器超時(shí)槽函數(shù),所以
* 定時(shí)器到時(shí)間了就會(huì)調(diào)用超時(shí)槽函數(shù)
* 對(duì)于 QTimerEvent不用重寫超時(shí)函數(shù)并且去手動(dòng)綁定,他會(huì)自動(dòng)調(diào)用timerEvent,只需要重寫這個(gè)就行
* */
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("定時(shí)器事件");
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);
//第一個(gè)標(biāo)簽
lab1 = new QLabel(this);
lab1->setFixedSize(95,95);
lab1->setFrameShape(QFrame::Box);
lab1->setStyleSheet("background-color:yellow");
vblayout->addWidget(lab1);
//第二個(gè)標(biāo)簽
lab2 = new QLabel(this);
lab2->setFixedSize(95,95);
lab2->setFrameShape(QFrame::Box);
lab2->setStyleSheet("background-color:purple");
vblayout->addWidget(lab2);
//三個(gè)按鈕
QPushButton* start= new QPushButton(this);
start->setText("開始");
QPushButton* pause= new QPushButton(this);
pause->setText("暫停");
QPushButton* restart= new QPushButton(this);
restart->setText("復(fù)位");
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);
//按鍵的信號(hào)槽
connect(start,&QPushButton::clicked,this,&TimerEvent::startclick);
connect(pause,&QPushButton::clicked,this,&TimerEvent::pauseclick);
connect(restart,&QPushButton::clicked,this,&TimerEvent::restartclick);
//Qtimer綁定的信號(hào)槽
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)
{
//當(dāng)定時(shí)器時(shí)間到了,看是哪個(gè)定時(shí)器
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點(diǎn) 總的來說,QTimer是最優(yōu)的定時(shí)器方案,有現(xiàn)成的封裝的很完善的功能,就用 QTimer就行。
使用QTimer的另一種選擇是為你的對(duì)象調(diào)用QObject::startTimer(),并在你的類(必須繼承QObject)中重新實(shí)現(xiàn)QObject::timerEvent()事件處理程序。缺點(diǎn)是timerEvent()不支持諸如單觸發(fā)定時(shí)器或信號(hào)之類的高級(jí)特性。
另一個(gè)替代方法是QBasicTimer。這通常比直接使用QObject::startTimer()要簡(jiǎn)單得多。
- 替代方法一:
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();
}
一些操作系統(tǒng)會(huì)限制可能使用的定時(shí)器的數(shù)目。Qt試圖繞過這些限制。
總結(jié)
到此這篇關(guān)于Qt兩種定時(shí)器使用的文章就介紹到這了,更多相關(guān)Qt定時(shí)器使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C/C++實(shí)現(xiàn)crc碼計(jì)算和校驗(yàn)
循環(huán)冗余校驗(yàn)(Cyclic Redundancy Check, CRC)是一種根據(jù)網(wǎng)絡(luò)數(shù)據(jù)包或計(jì)算機(jī)文件等數(shù)據(jù)產(chǎn)生簡(jiǎn)短固定位數(shù)校驗(yàn)碼的一種信道編碼技術(shù)。本文主要介紹了C++實(shí)現(xiàn)crc碼計(jì)算和校驗(yàn)的方法,需要的可以參考一下2023-03-03
C語言使用鏈表實(shí)現(xiàn)學(xué)生籍貫管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言使用鏈表實(shí)現(xiàn)學(xué)生籍貫管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

