Qt兩種定時(shí)器使用實(shí)現(xiàn)方式
QT 中使用定時(shí)器,有兩種方式:
- 定時(shí)器類(lèi):
QTimer
- 定時(shí)器事件:
QEvent::Timer
,對(duì)應(yīng)的子類(lèi)是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í)器的
- 這樣通過(guò)按鈕點(diǎn)擊之后,調(diào)用里面Qtimer的start,因?yàn)橥饷娼壎硕〞r(shí)器超時(shí)槽函數(shù),所以
- 定時(shí)器到時(shí)間了就會(huì)調(diào)用超時(shí)槽函數(shù),完成業(yè)務(wù)邏輯
QTimerEvent:
- 需要重寫(xiě)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不用重寫(xiě)定時(shí)器超時(shí)函數(shù)并且再手動(dòng)綁定,QTimerEvent他會(huì)自動(dòng)調(diào)用timerEvent,該函數(shù)將自動(dòng)在使用startTimer函數(shù)啟動(dòng)的定時(shí)器到期時(shí)被調(diào)用,所以只需要重寫(xiě)這個(gè)就行
下面舉一個(gè)案例:看看實(shí)際項(xiàng)目中怎么用
這有一個(gè)定時(shí)器任務(wù)的頁(yè)面,無(wú)ui的,手撕代碼去寫(xiě)
.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類(lèi),一種是QEvent的Timer事件 ,用到的子類(lèi)是QTimerEvent * 用兩種都去實(shí)現(xiàn)一下 * 1.QTimerEvent * 需要重寫(xiě)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í)器的 * 這樣通過(guò)按鈕點(diǎn)擊之后,調(diào)用里面Qtimer的start,因?yàn)橥饷娼壎硕〞r(shí)器超時(shí)槽函數(shù),所以 * 定時(shí)器到時(shí)間了就會(huì)調(diào)用超時(shí)槽函數(shù) * 對(duì)于 QTimerEvent不用重寫(xiě)超時(shí)函數(shù)并且去手動(dòng)綁定,他會(huì)自動(dòng)調(diào)用timerEvent,只需要重寫(xiě)這個(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("開(kāi)始"); 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) 總的來(lái)說(shuō),QTimer是最優(yōu)的定時(shí)器方案,有現(xiàn)成的封裝的很完善的功能,就用 QTimer就行。
使用QTimer的另一種選擇是為你的對(duì)象調(diào)用QObject::startTimer(),并在你的類(lèi)(必須繼承QObject)中重新實(shí)現(xiàn)QObject::timerEvent()事件處理程序。缺點(diǎn)是timerEvent()不支持諸如單觸發(fā)定時(shí)器或信號(hào)之類(lèi)的高級(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試圖繞過(guò)這些限制。
總結(jié)
到此這篇關(guān)于Qt兩種定時(shí)器使用的文章就介紹到這了,更多相關(guān)Qt定時(shí)器使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07C/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-03C語(yǔ)言使用鏈表實(shí)現(xiàn)學(xué)生籍貫管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言使用鏈表實(shí)現(xiàn)學(xué)生籍貫管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02