注意事项:
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()的总耗时