• 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()的总耗时

  • 相关阅读:
    dnsever 邮件记录
    用于显示上个月和下个月_PHP
    JSON学习
    ASP生成新会员编号
    godaddy_关于产品退款
    Switch Case语句中多个值匹配同一个代码块的写法
    网闸与防火墙的比较
    bench.sh 跑分测速
    Kcptun加速SS
    linux 安全狗
  • 原文地址:https://www.cnblogs.com/likemao/p/8722331.html
Copyright © 2020-2023  润新知