zoukankan      html  css  js  c++  java
  • QTimer

    简述

    QTimer类提供了重复和单次触发信号的定时器。

    QTimer类为定时器提供了一个高级别的编程接口。很容易使用:首先,创建一个QTimer,连接timeout()信号到适当的槽函数 , 并调用start(),然后在恒定的时间间隔会发射timeout()信号。

    注意:当QTimer的父对象被销毁时,它也会被自动销毁。

    详细说明

    1秒(1000毫秒)更新一次:

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);
    
    //Widget::Widget(QWidget *parent)
    //    : QWidget(parent)
    //{
    //    QTimer *timer = new QTimer(this);
    //    QObject::connect(timer,&QTimer::timeout,this,[=](){
    //        qDebug() <<"定时器触发了";
    //    });
    //    timer->start();// 缺省就是0毫妙
    //}
    
    
    

    start()之后,每秒都会调用update()可以通过设置setSingleShot(true)来让定时器只执行一次。也可以使用静态函数QTimer::singleShot():

    QTimer::singleShot(200, this, SLOT(updateCaption()));

    在多线程程序中,可以在一个有事件循环的任何线程中使用QTimer。使用QThread::exec(),从非GUI线程启动一个事件循环。
    Qt使用定时器的线程关联,以确定哪个线程会发出timeout()信号。正因为如此,你必须在它的线程中启动和停止定时器,不可能从另一个线程启动定时器。

    作为一个特例,一旦窗口系统事件队列中的所有事件都已经被处理完,一个定时为0的QTimer就会到时间了。当需要提供流畅的用户界面时,可以用这来做比较繁重的工作。

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()),  this, SLOT(processOneThing()));
    timer->start();
    

    这时,processOneThing()将会被重复调用并且应该很快返回(通常在处理一个数据项之后),这样Qt可以把事件传送给窗口部件,并且一旦它完成这个工作就停止这个定时器。这是在图形用户界面应用程序中实现繁重的工作的一个典型方法,现在多线程可以在越来越多的平台上使用,我们希望0-毫秒QTimer对象最终被线程替代。 其实这样是不对的,能有代替多线程的方案尽量不用多线程。

    精度

    定时器的精度取决于底层操作系统和硬件。绝大多数平台支持精度为1毫秒,尽管定时器的准确性在许多现实世界的情况下和这不相符。

    准确性也取决于定时器类型(Qt::TimerType)。对于Qt::PreciseTimer来说,QTimer将试图保持精确度在1毫秒。精确的定时器也从来不会比预计的还要早超时。

    对于Qt::CoarseTimer和Qt::VeryCoarseTimer类型,QTimer可能早于预期,在间隔之内被唤醒:Qt::CoarseTimer为间隔的5%,Qt::VeryCoarseTimer为500毫秒。

    枚举Qt::TimerType:

    常量 描述
    Qt::PreciseTimer 0 精确的定时器,尽量保持毫秒精度。
    Qt::CoarseTimer 1 粗略的定时器,尽量保持精度在所需的时间间隔5%范围内。
    Qt::VeryCoarseTimer 2 很粗略的定时器,只保留完整的第二精度。

    在UNIX (包括: Linux、OS X、iOS)中,Qt将为Qt::PreciseTimer保持毫秒精度,对于Qt::CoarseTimer,间隔将调整到5%,使定时器与其他定时器匹配或在差不多在同一时间,目标是让大多数定时器在同一时间醒来,从而减少CPU唤醒和功耗。

    在Windows上,Qt将为Qt::PreciseTimer使用Windows的多媒体定时器工具(如果可用),为Qt::CoarseTimer和Qt::VeryCoarseTimer使用正常的Windows定时器。

    所有平台上,Qt::VeryCoarseTimer的间隔被四舍五入到最接近完整的第二位(例如:23500ms的时间间隔将被舍入到24000ms,20300ms舍入至20000)。

    替代QTimer

    • 另一个使用QTimer的方法:为你的对象调用QObject::startTimer(),在你的类中(必须继承QObject)重新实现QObject::timerEvent()事件处理器。缺点是timerEvent()不支持像单次触发定时器或信号那样的高级特性。

    • 另一个选择是QBasicTimer。它通常比使用QObject::startTimer() 直接。可以查看助手中Timers描述的三种方法。
      一些操作系统限制可能会限制定时器的数量,Qt会尽力在限制范围内工作。

    可参考:QBasicTimer、QTimerEvent、QObject::timerEvent()、Timers、Analog Clock Example、Wiggly Example。

    成员函数

    bool isActive() const
    如果定时器正在运行,返回true,否则返回false。
    
    int remainingTime() const
    返回定时器的剩余时间(毫秒为单位),直到超时。
    
    如果定时器不活跃,返回值是-1。如果定时器过期,返回值为0。
    
    void setInterval(int msec)
    设置超时间隔(毫秒为单位)。
    
    默认值是0,这时,一旦窗口系统事件队列中的所有事件都已经被处理完,一个时间间隔为0的QTimer就会触发。
    
    void setSingleShot(bool singleShot)
    设置定时器是否为单次触发。
    
    单次触发定时器只触发一次,非单次的话,则每过一个时间间隔都会触发。
    
    void setTimerType(Qt::TimerType atype)
    设置定时器的准确性。默认值是Qt::CoarseTimer。
    
    int timerId() const
    如果定时器正在运行,返回定时器的ID,否则返回-1。
    
    void start(int msec)
    启动或重新启动一个超时时间间隔为毫秒的定时器。
    
    如果定时器正在运行,它将被停止和重新启动。如果singleShot为true,定时器将只激活一次。
    
    void start()
    同上,重载了start()。
    
    void stop()
    停止定时器。
    

    信号

    void timeout()
    定时器超时后,这个信号被发射。
    
    注意:这是一个私有的信号。它可以在信号连接使用,但不能由用户发出。
    

    示例

    下面,我们以QTimer为例,利用开始和停止按钮来操作一个进度条的更新。

    // .h
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QProgressBar>
    #include <QTimer>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = 0);
        ~Widget();
    
    private:
        QProgressBar *m_progressbar;
        QTimer *m_timer;
    
    private slots:
        void updataProgressBar();
    };
    
    #endif // WIDGET_H
    
    
    //.cpp
    
    #include "widget.h"
    #include <QDebug>
    #include <QPushButton>
    #include <QHBoxLayout>
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        QPushButton *btn_start =  new QPushButton(this);
        QPushButton *btn_stop = new QPushButton(this);
        m_progressbar = new QProgressBar(this);
        m_timer = new QTimer(this);
    
        QHBoxLayout *layout = new QHBoxLayout(this);
        layout->addWidget(m_progressbar);
        layout->addWidget(btn_start);
        layout->addWidget(btn_stop);
        setLayout(layout);
    
        btn_start->setText(tr("start"));
        btn_stop->setText(tr("stop"));
    
        m_progressbar->setOrientation(Qt::Horizontal);
        m_progressbar->setRange(0,100);
        m_progressbar->setValue(0);
        // 设置时间间隔
        m_timer->setInterval(1000);
        //singal slots
        connect(btn_start,&QPushButton::clicked,m_timer,static_cast<void(QTimer::*)()>(&QTimer::start));
        connect(btn_stop,&QPushButton::clicked,m_timer,&QTimer::stop);
        connect(m_timer,&QTimer::timeout,this,&Widget::updataProgressBar);
    
    }
    
    Widget::~Widget()
    {
    
    }
    
    void Widget::updataProgressBar()
    {
        // 获取当前进度值,+1
        int nCurrentValue = m_progressbar->value();
        ++nCurrentValue;
    
        if(nCurrentValue >=100){
            m_timer->stop();
        }
        // 设置新的进度值
        m_progressbar->setValue(nCurrentValue);
    
    }
    

    在槽函数updataProgressBar()中,首先通过m_progressbar->value()来获取当前进度值,然后加1,当进度大于等于100时停止定时器(再继续执行已经没任何意义了,因为进度已经达到了100,而且不停止还消耗资源),然后设置进度条的值。

    参考处 :https://blog.csdn.net/liang19890820/article/details/51789796

  • 相关阅读:
    Java语言基础(3)
    Java语言基础(2)
    Java语言基础(1)
    标准C语言(13)
    标准C语言(12)
    标准C语言(11)
    标准C语言(10)
    IDEA 学习笔记之 Console显示日志大小
    Java 学习笔记之 线程sleep方法
    Java 学习笔记之 线程isAlive方法
  • 原文地址:https://www.cnblogs.com/__tudou__/p/11606409.html
Copyright © 2011-2022 走看看