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ù)的頁(yè)面,無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)文章希望大家以后多多支持腳本之家!
- Qt定時(shí)器(QTimer)的3種使用方法
- Qt定時(shí)器類QTimer使用詳解與注意事項(xiàng)
- QT定時(shí)器事件的實(shí)現(xiàn)示例
- Qt使用事件與定時(shí)器實(shí)現(xiàn)字幕滾動(dòng)效果
- Qt實(shí)現(xiàn)定時(shí)器的兩種方法分享
- Qt實(shí)現(xiàn)高精度定時(shí)器
- Qt實(shí)現(xiàn)線程與定時(shí)器的方法
- Qt基于定時(shí)器實(shí)現(xiàn)動(dòng)圖展示效果
- Qt基礎(chǔ)開發(fā)之Qt多線程類QThread與Qt定時(shí)器類QTimer的詳細(xì)方法與實(shí)例
- Qt定時(shí)器和隨機(jī)數(shù)詳解
- Qt中定時(shí)器 QTimerEvent 和 QTimer的使用
相關(guān)文章
VS2022添加代碼模板的實(shí)現(xiàn)步驟(圖文)
使用代碼模板即可實(shí)現(xiàn)像內(nèi)置函數(shù)那樣,只需寫幾個(gè)字母,便能提示自動(dòng)補(bǔ)全,本文主要介紹了VS2022添加代碼模板的實(shí)現(xiàn)步驟,感興趣的可以了解一下2024-06-06
QT中在QLabel顯示圖片并且利用鼠標(biāo)點(diǎn)擊畫線問題
這篇文章主要介紹了QT中在QLabel顯示圖片并且利用鼠標(biāo)點(diǎn)擊畫線問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
C語言順序表的基本操作(初始化,插入,刪除,查詢,擴(kuò)容,打印,清空等)
這篇文章主要介紹了C語言順序表的基本操作(初始化,插入,刪除,查詢,擴(kuò)容,打印,清空等),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-02-02
關(guān)于虛函數(shù)實(shí)現(xiàn)多態(tài)的原理及分析
這篇文章主要介紹了C++中如何實(shí)現(xiàn)多態(tài)問題,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)選擇題標(biāo)準(zhǔn)化考試系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
C++?Boost?MultiArray簡(jiǎn)化使用多維數(shù)組庫(kù)
Boost是為C++語言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱2022-11-11

