简述

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

QTimer的更多相关文章

  1. QTimer的用法

    1.singleShot的用法 代码: QTextEdit *testEdit = new QTextEdit("hello world"); testEdit->setMa ...

  2. pyqt4:在线程Qthread中使用定时器Qtimer

    GUI main 部分,主app类中的__init__初始化方法中添加 实例化线程 self.s2_thread=Worker2() 初始化一个定时器 self.log_get=QtCore.QTim ...

  3. QT QDateTime类、QTimer类

    QDateTime类,头文件#include <QDateTime> 可以使用QDateTime类来获得系统时间.通过QDateTime::currentDateTime()来获取本地系统 ...

  4. QTimer太让人失望了,一秒触发一次事件都不准确。。

    今天做项目中,我用QTimer来模拟数据生成,在另外的设备上接受.另外设备上有时1秒读不到数据,查询原因很久,终于发现是QTimer的问题. 测试代码如下 有兴趣同学可以自己试试. t = new Q ...

  5. Qt之等待提示框(QTimer)

    简述 上节讲述了关于QPropertyAnimation实现等待提示框的显示,本节我们使用另外一种方案来实现-使用定时器QTimer,通过设置超时时间定时更新图标达到旋转效果. 简述 效果 资源 源码 ...

  6. QTimer源码分析(以Windows下实现为例)

    QTimer源码分析(以Windows下实现为例) 分类: Qt2011-04-13 21:32 5026人阅读 评论(0) 收藏 举报 windowstimerqtoptimizationcallb ...

  7. CPU满格的元凶,这回是由于QTimer引起的(默认interval是0,太猛)

    timer_space = new QTimer(); qDebug() << SystemGlobal::m_app->SpaceUse; qDebug() << ti ...

  8. 为进度条增加“伪进度条”?(使用QEventLoop和QTimer)

    在实际开发中,可能会遇到这样的场景:“一个操作非常耗时,但却无法获取其进度百分比”.造成这种情况的原因可能有: 1)该操作属于第三方库(泛指我们使用但无法修改的第三方代码,因此质量有高有底),可能由于 ...

  9. Qt中使用定时器(可使用QObject::timerEvent定时执行,QTimer::singleShot可只触发一次)

    在Qt中使用定时器有两种方法,一种是使用QObiect类的定时器:一种是使用QTimer类.定时器的精确性依赖于操作系统和硬件,大多数平台支持20ms的精确度 1.QObject类的定时器 QObje ...

  10. QTimer在QThread环境中失效的问题

    QTimer在非QThread的环境下能正常工作.但在QThread环境下,需要做一些改动才能正常工作. 创建Qt的线程有两种方式: 1. 子例化QThread 可以在虚函数run中启动定时器,大致的 ...

随机推荐

  1. vulstack红队评估(三)

    一.环境搭建: ①根据作者公开的靶机信息整理 没有虚拟机密码,纯黑盒测试...一共是5台机器,目标是拿下域控获取flag文件   ②虚拟机网卡设置 centos双网卡模拟内外网: 外网:192.168 ...

  2. chromedp入门

    chromedp入门 chromedp是什么? chromedp是go写的,支持Chrome DevTools Protocol 的一个驱动浏览器的库.并且它不需要依赖其他的外界服务(比如 Selen ...

  3. PHPWord中文乱码、单元格合并、动态表格模板解决方案合集

    摘要:  最近一个项目开发要用到PHP技术导出Word文档,采用PHPWord插件,版本为0.6.2 beta,CodePlex已停止维护.网上还有另外一个版本的PhpWord,项目类名大小写上略有不 ...

  4. Halcon斑点分析BlobAnalysis解析

    斑点分析的算法非常简单:在图像中,相关对象的像素(也称为前景)通过其灰度值来识别.例如,图中示例显示了液体中的组织颗粒.这些粒子是明亮的,液体(背景)是暗的.通过选择明亮的像素(阈值),可以很容易检测 ...

  5. FreeSql 使用 ToTreeList/AsTreeCte 查询无限级分类表

    关于无限级分类 第一种方案: 使用递归算法,也是使用频率最多的,大部分开源程序也是这么处理,不过一般都只用到四级分类. 这种算法的数据库结构设计最为简单.category表中一个字段id,一个字段fi ...

  6. dart快速入门教程 (4)

    4.流程控制 4.1.分支结构 1.if语句 void main() { int score = 80; if (score >= 90) { print('优秀'); } else if (s ...

  7. jQuery动态生成<select>下拉框

    前一阵在项目里需要动态生成下拉框,找了一下用jQuery实现比较方便,这里整理一下. 下文所述方法只是本人在项目中遇到问题的解决方法,场景较为简单,也希望能帮助有需要的朋友 1.动态生成下拉框的两种方 ...

  8. JavaScript基础尽量少使用全局变量(001)

    Pattern意思是模式,好的编码习惯经过多次实践的应用就会形成模式,而反模式(Anti-Pattern)则是不好的编码习惯.了解 JavaScript模式之前,先来看看Anti-pattern的例子 ...

  9. Mybatis 动态insert语句

    mybatis的一个比较先进的思想是把Sql语句写在了配置xml文件(也支持注解),通过配置文件的方式,免去了一般软件开发的硬编码,当业务需求改变的时候,只需要更改sql语句即可! 下面是个人在学习m ...

  10. Netty系列之源码解析(一)

    本文首发于微信公众号[猿灯塔],转载引用请说明出处 接下来的时间灯塔君持续更新Netty系列一共九篇 当前:Netty 源码解析(一)开始 Netty 源码解析(二): Netty 的 Channel ...