Qt之QTimer
简述
QTimer类提供了重复和单次触发信号的定时器。
QTimer类为定时器提供了一个高级别的编程接口。很容易使用:首先,创建一个QTimer,连接timeout()信号到适当的槽函数,并调用start(),然后在恒定的时间间隔会发射timeout()信号。
注意:当QTimer的父对象被销毁时,它也会被自动销毁。
详细说明
在Qt之模拟时钟中,1秒(1000毫秒)更新一次:
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
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为例,利用开始和停止按钮来操作一个进度条的更新。
效果
源码
QPushButton *pStartButton = new QPushButton(this);
QPushButton *pStopButton = new QPushButton(this);
m_pProgressBar = new QProgressBar(this);
m_pTimer = new QTimer();
pStartButton->setText(QString::fromLocal8Bit("开始"));
pStopButton->setText(QString::fromLocal8Bit("停止"));
m_pProgressBar->setRange(0, 100);
m_pProgressBar->setValue(50);
// 设置超时间隔
m_pTimer->setInterval(1000);
// 连接信号槽
connect(pStartButton, SIGNAL(clicked(bool)), m_pTimer, SLOT(start()));
connect(pStopButton, SIGNAL(clicked(bool)), m_pTimer, SLOT(stop()));
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(updateProgress()));
// 槽函数
void MainWindow::updateProgress()
{
// 获取当前进度值,+1
int nCurrentValue = m_pProgressBar->value();
nCurrentValue++;
if (nCurrentValue >= 100)
m_pTimer->stop();
// 设置新的进度值
m_pProgressBar->setValue(nCurrentValue);
}
在槽函数updateProgress()中,首先通过m_pProgressBar->value()来获取当前进度值,然后加1,当进度大于等于100时停止定时器(再继续执行已经没任何意义了,因为进度已经达到了100,而且不停止还消耗资源),然后设置进度条的值。
更多参考
Qt之QTimer的更多相关文章
- qt 利用Qtimer 定时器实现定时消息发送
为了实现给控制器按周期发送控制指令,利用qt中的Qtimer 实现消息的定时发送. 需要进行三步处理: 1.在mainwindow.h文件中对timerEvent进行声明 public virtual ...
- Qt:QTimer
1.说明 QTimer类代表计时器,为了正确使用计时器,可以构造一个QTimer,将它的timeout()信号connect到合适的槽,之后调用start().然后,这个QTimer就会每隔inter ...
- Qt QPropertyAnimation+QTimer实现自制悬浮窗
目录 Qt下的悬浮窗 QPropertyAnimation QTimer 事件过滤 图标变换 自适应窗口大小 使用方法 Qt下的悬浮窗 最近项目需要一个类似于360悬浮球类似的悬浮窗,当鼠标放入停留一 ...
- Qt QDateTime QTimer的简单实用
转载:N3verL4nd qttimer.h #ifndef QTTIMER_H #define QTTIMER_H #include <QDialog> namespace Ui { c ...
- 《Qt 实战一二三》
简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的 ...
- QT:窗口最小化时显示一个小浮标
有些窗口在自身最小化时要在桌面上显示一个小浮标,让用户利用这个小浮标进行各种操作(例如迅雷的悬浮窗一样),我试着用QT实现一下这个功能. PS:本来以为这个功能很简单,却搞了我两个晚上,泪奔... 思 ...
- Qt多线程学习-用例子来理解多线程
文章出处:DIY部落(http://www.diybl.com/course/3_program/c/c_js/20090303/157373_3.html) POINT 1:QThread类的实例与 ...
- Qt中的内存回收机制
Qt中的内存回收机制 在Qt中创建对象的时候会提供一个 Parent对象指针(可以查看类的构造函数),下面来解释这个parent到底是干什么的. QObject是以对象树的形式组织起来的.当你创建一个 ...
- 词频统计_输入到文件_update
/* 输入文件见337.in.txt 输出文件见338.out.txt */ #include <iostream> #include <cctype> #include &l ...
随机推荐
- [读书笔记] R语言实战 (十四) 主成分和因子分析
主成分分析和探索性因子分析是用来探索和简化多变量复杂关系的常用方法,能解决信息过度复杂的多变量数据问题. 主成分分析PCA:一种数据降维技巧,将大量相关变量转化为一组很少的不相关变量,这些无关变量称为 ...
- BeanUtils(前端赋值给后台,忽略空属性)
package com.drn.core.util; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; im ...
- Android开发进度06
1,今日:目标:完成后台账单的增删改查 2,昨天:用户的增删改查 3,收获:熟练了SQLite操作 4,问题:无
- 紫书 习题7-8 UVa 12107 (IDA*)
参考了这哥们的博客 https://blog.csdn.net/hyqsblog/article/details/46980287 (1)atoi可以char数组转int, 头文件 cstdlib ...
- FROM使用子查询
FROM使用子查询 子查询结果充当一个临时表. //子查询形成的临时表字段为NO,NAME,SAL select no,name from( select empno no,e ...
- CODEVS——T 1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛
http://codevs.cn/problem/1269/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Descript ...
- intellij idea 打开两个 terminal
intellij idea 打开两个 terminal alt+f12可以打开terminal,在terminal窗口左侧点击绿色的加号,就可以又打开一个terminal,用tab标签展示:
- Hadoop学习;測试;启动bug;secondary合并edits到fsimage
一个Hadoop集群拥有多个并行的计算机.用以存储和处理大规模的数据集 Hadoop强调代码向数据迁移 要执行的程序在规模上比数据小的多,更easy移动,此外通过网络移动数据比载入执行程序更花时间,这 ...
- 【SPOJ-GSHOP】Rama and Friends【贪心】【细节】
题意: 给出n个非严格递增的整数(可能有负数),必须操作k次.每次能够把当中一个数变为它的相反数,使得终于的数列和最大. 输出这个最大和. 考验怎样出坑数据卡自己的程序... #include < ...
- [JZOJ NOIP2018模拟10.20 A组]
由于T3数据出锅,还不清楚自己的分数...估分150,前100已经拿到了,T3的50没拍过(写的就是暴力怎么拍),感觉很不稳 考试的时候就是特别的困,大概是因为早上在房间里腐败...腐败完了才睡觉 T ...