QTimer的一些注意事項和探索


注意事項:

1、QTimer's accuracy depends on the underlying operating system and hardware.Most platforms support an accuracy of 20 milliseconds; some provide more.

2、If Qt is unable to deliver the requested number of timer events, it will silently discard some.

 

問題:當開啟一個定時器,設置時間間隔為50ms,它對應的QTimerEvnet處理函數要執行一段耗時的操作,如何讓界面快速響應用戶的鼠標事件呢

代碼:

#include "QtGuiApplication2.h"
#include <QDebug>
#include <QTimerEvent>
#include <QDateTime>
#include <QTime>
#include <QThread>

QtGuiApplication2::QtGuiApplication2(QWidget *parent)
    : QDialog(parent)
{
    ui.setupUi(this);
    startTimer(50);
    connect(ui.pushButton, &QPushButton::clicked, this, &QtGuiApplication2::showCurrentTime);
}

void QtGuiApplication2::timerEvent(QTimerEvent *event)
{
    //QThread::msleep(2000);這個和下面的效果是一樣的
    QTime qTime1 = QTime::currentTime();
    while (qTime1.msecsTo(QTime::currentTime())<2000)
        qDebug() << "do nothing just for test";
}

void QtGuiApplication2::showCurrentTime()
{
    ui.label->setText(QDateTime::currentDateTime().toString("hh:mm:ss.zzz"));
}

Ui:

當運行程序的時候,點擊按鈕發現textLabel的響應時間差不多是2秒,通過text顯示的時間可以計算出來

 

解決方法:

void QtGuiApplication2::timerEvent(QTimerEvent *event)
{
    //QThread::msleep(2000);
     QTime qTime1 = QTime::currentTime();
    while (qTime1.msecsTo(QTime::currentTime()) < 2000) {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
        qDebug() << "do nothing just for test";
    }
        
}

這個解決了操作耗時的情況,但是當你選擇QThread::msleep(2000);那怎么都會卡了

 

 


 

疑問:

假設當前時刻為0;程序開始運行;100ms時刻,我按下按鈕;此時事件隊列里面應該有QTimerEvent;QTimerEvent;QMousePress這三個事件要處理,按理說Label的時間相應應該是4s左右啊,可能的解釋就是If Qt is unable to deliver the requested number of timer events, it will silently discard some.因此它丟棄了QMousePress之前相同的QTimerEvent

 此實驗驗證了這個觀念:

#include <QtWidgets/QDialog>
#include <QTime>
#include "ui_QtGuiApplication2.h"

class QtGuiApplication2 : public QDialog
{
    Q_OBJECT

public:
    QtGuiApplication2(QWidget *parent = Q_NULLPTR);
protected:
    void timerEvent(QTimerEvent *event) override;
    void showCurrentTime();
private:
    Ui::QtGuiApplication2Class ui;
    int id;
    QTime lastTime;
};

 

QtGuiApplication2::QtGuiApplication2(QWidget *parent)
    : QDialog(parent)
{
    ui.setupUi(this);
    startTimer(50);
    id = startTimer(1000);
    lastTime = QTime::currentTime();
}

void QtGuiApplication2::timerEvent(QTimerEvent *event)
{
    qDebug() << "current timer id:  " << event->timerId();
    if (event->timerId() == id) {
        ui.label->setText(QString::number(lastTime.msecsTo(QTime::currentTime())));
        lastTime= QTime::currentTime();
    }    
}

通過界面的Label顯示基本都是1014左右;多出來的14毫秒就是執行50msQTimerEvent的輸出語句和 lastTime= QTime::currentTime()的總耗時;

因此可以推測出:

當有個定時器在事件隊列里有很多個QTimerEvent;那么當有另外一個事件A到了,在執行完當前的QTimerEvent之后它會丟棄A之前其他QTimerEvent;直接執行事件A

所以14毫秒就是執行50msQTimerEvent的輸出語句和 lastTime= QTime::currentTime()的總耗時

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM