QElapsedTimer提供了一种快捷的计算流逝时间的方法。它通常被用来计算两个事件或操作之间过去了多久。并且,该类的方法非常类似于我们之前讲过的QTime类的三个计时函数,所以,我们可以很快速的在使用这两个类的代码之间进行移植。但是,不像QTime,QElapsedTimer会尽可能的使用某种单调时钟。这也就意味着,没办法将QElapsedTimer对象转换成人类可读的时间格式。

这个类的典型使用方法就是测量一个耗时操作花了多少时间。最简单的例子如下:

QElapsedTimer timer;
timer.start();
slowOperation1();
qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds";  

在这个例子中,我们下定义了一个QElapsedTimer的对象,然后调用它的start() 方法开始计时,完成一个耗时操作后,再调用它的elapsed() 方法,得到耗时操作所花费的具体时间,以毫秒计算。

我们也可以在一个耗时操作完成后,通过elapsed() 函数的返回值来决定下一个耗时操作可以运行的时间。这对于需要在一定的时间周期内完成几个耗时操作来说是至关重要的。比如下面代码所展现的案例:

void executeSlowOperations(int timeout)
{  QElapsedTimer timer;  timer.start();  slowOperation1();  int remainingTime = timeout - timer.elapsed();  if (remainingTime > 0)  slowOperation2(remainingTime);
}  

另一个QElapsedTimer的使用案例是,一个具体的操作需要运行一定的时间长度。对于这种需求,QElapsedTimer提供了hasExpired() 函数,这个函数可以判断自从上次调用start() 或restart() 之后,是否过去了多少毫秒。如下代码所示:

void executeOperationsForTime(int ms)
{  QElapsedTimer timer;  timer.start();  while (!timer.hasExpired(ms))  slowOperation1();
}  

上面我们说,QElapsedTimer会使用运行平台所支持的某种单调参考时钟。这具有额外的好处,它可以使QElapsedTimer不受系统时间调整的影响,也不受系统时区设置的影响。当然,相对的,这也意味着我们只能把QElapsedTimer的值和那些使用了同样参考时钟的值相比较。特别是,当我们把QElapsedTimer的自从参考点以来的值序列化到某个变量中后,更应该注意这点。并且,不应该把这些值通过网络进行交换或存储到磁盘,因为无法保证接收端的计算机和产生该值的计算机是否使用同一种参考时钟和参考点,也无法保证其自从参考点以来是否发生过重启。但是,我们可以将这些值在运行在同一太机器上的不同进程间进行交换,条件是他们都使用相同的参考时钟。QElapsedTimer在同一台机器上总是使用相同的参考时钟,所以,在一个进程中比较来自另一个进程的QElapsedTimer值是安全的。

注意,QElapsedTimer所使用的时钟类型,有一些是有范围限制的,通常是32-bit,当达到上限时会发生溢出。QElapsedTimer会处理这种情况并提供一致时间。但是,当从QElapsedTimer中提取时间时,同一机器上的两个不同的进程会对实际逝去的时间有不同的理解。

下面,我们就来具体看下QElapsedTimer所使用的集中时钟类型:

SystemTime

该类型的时钟是唯一一种表示实时时间的时钟,它表示子1970.1.1零点以来的毫秒数。它就相当于C或POSIX中的time() 函数,外加毫秒值。这种时钟类型目前只用于不支持 单调时钟的Unix系统。它也是QElapsedTimer可能使用的唯一一种非单调时钟。

MonotonicClock

表示系统的单调时钟,表示的是自过去任意时间点以来的毫秒数。这种时钟类型用于支持POSIX时钟类型的Unix系统(_POSIX_MONOTONIC_CLOCK)。并且,这种时钟类型不会发生溢出。

TickCounter

这种时钟类型的计时基于系统的或处理器的tick数,然后再乘以一个tick的周期。这种时钟类型用于Windows系统。并且,当高精度的性能计数器可用时,会自动使用PerformanceCounter替代这种时钟类型。TickCounter是唯一一种可能发生溢出的时钟类型。但在Windows Vista 和 Windows server 2008上,由于它们支持扩展的64-bit  tick  counter,可以避免溢出。

在Windows平台,时钟会在2^32毫秒,即大约49.7天后溢出。这也意味着两个不同的进程通过乘以2^32毫秒来计算逝去的时间,得到的结果可能是不同的。当进行这类数值得比较时,我们建议将毫秒的高32位屏蔽掉。

MachAbsoluteTime

这种时钟类型是基于Mach kernels 表示的绝对时间,例如 OS X。把这种时钟类型和MonotonicClock区分开是因为OS X 和 IOS也是Unix系统,也可能支持一种和Mach绝对 时间具有不同值的POSIX单调时钟。这种时钟是单调的并且不会发生溢出。

PerformanceCounter

这种时钟类型使用Windows的QueryPerformanceCounter() 和 QueryPerformanceFrequency() 函数访问系统的高精度性能计数器。但因为这种计数器并不是在所有平台上都可用,所以,QElapsedTimer会在该时钟类型不可用时,自动使用TickCounter作为替代。这种时钟类型也是单调的并且不会发生溢出。

搞明白每一种可用的时钟类型和单调性后,我们可以在程序中使用clockType() 函数来获得一个QElapsedTimer对象所使用的底层时钟类型;使用isMonotonic() 函数判断一个QElapsedTimer对象的单调性。

最后,至于该类的使用方式,上面的例子也说的差不多了,最常用的就是start()、restart()、elapsed()这些函数。其他的函数,大家在需要时可以参考Qt帮助文档。

参考:

https://www.yuque.com/docs/share/514a4f70-d0fc-4ff7-8822-c776029a1de8

QElapsedTimer 计时器相关推荐

  1. QElapsedTimer计时

    文章目录 前言 1.头文件和命名空间 2.创建QElapsedTimer对象 3.获取已过时间 4.检查计时器是否在运行 5.停止计时器 6.获取计时器的分辨率 使用QElapsedTimer时需要注 ...

  2. Android 计时器 Chronometer

    Android 简单的计时器可以使用系统提供的方法Chronometer 下面是是实现的效果 Chronometer 的几个方法如下: 1  start(); 计时开始 2 stop(); 计时暂停 ...

  3. 时间计时android程序,Android 时间计时器控件 Chronometer

    当你想要显示时间的推移而不是进程的增加的时候,可以使用Chronometer作为一个计时器.当需要记录用户进行某项操作所消耗的时间的时候,或者在游戏中需要限制时间时候,它将非常实用. 这里,Chron ...

  4. Python Qt GUI设计:QTimer计时器类、QThread多线程类和事件处理类(基础篇—8)

    目录 1.QTimer计时器类 2.QThread多线程类 3.事件处理类 一般情况下,应用程序都是单线程运行的,但是对于GUI程序来说,单线程有时候满足不了需求.例如,如果需要执行一个特别耗时的操作 ...

  5. 封装一个计时器,记录页面的停留时间

    在页面加载时初始化计时器,页面结束时取值. 效果如图: 下面是uniapp的代码示例: <template><view class="aaaacc">< ...

  6. javascript计时器_JavaScript计时器:您需要了解的一切

    javascript计时器 by Samer Buna 通过Samer Buna JavaScript计时器:您需要了解的一切 (JavaScript Timers: Everything you n ...

  7. c纳秒级计时器_C++11 计时器!真香

    C++11 计时器!真香 一.前言 在我们写程序过程中,有时候需要测试我们的程序语句执行时间的耗时,当前也是有很多的库提供我们去使用,一直没有良好的跨平台的库可以提供出来:而且一般这种代码也是由我们程 ...

  8. easyui treegrid 获取新添加行inserted_18行JavaScript代码构建一个倒数计时器

    有时候,你会需要构建一个JavaScript倒计时时钟.你可能会有一个活动.一个销售.一个促销或一个游戏.你可以用原生的JavaScript构建一个时钟,而不是去找一个插件.尽管有很多很棒的时钟插件, ...

  9. Java计时器Timer和TimerTask用法总结(源码)

    在家学技术实在是不好坚持,心里老是想给自己放个假,但是现在俺又太菜,又想赶赶技术.前天做一个五子棋程序, 遇到了计时器功能的需求,但是这个我没用过,就总结一下吧,不过虽然是会用了,但是和swing的代 ...

最新文章

  1. Usage and Idioms——Categories
  2. Linux-鸟菜-7-Linux文件系统-EXT
  3. Python基础教程:生成器
  4. 线性代数之矩阵标准型的求法
  5. 数据仓库分层和元数据管理
  6. script 标签到底该放在哪里
  7. js undefined 相等_你知道JS中==和===区别吗?
  8. win32SDK的hello,world程序(二)
  9. 2021-2027全球与中国自动识别和数据采集设备市场现状及未来发展趋势
  10. 微信协议简单调研笔记 (2)
  11. 麦肯锡教我的思考武器-读书心得
  12. php网页显示左中,php的动态页面在ie内核的浏览器面整体偏左的解决方法静
  13. 开发一款APP需要阿里云服务器多大配置
  14. 古巴比伦理财五大金科定律
  15. python libusb_python, libusb, pyusb
  16. 制作ESXI6.7启动盘
  17. oracle测试实用SQL语句
  18. 三、C语言常用的库函数
  19. 由感而发:离职的第四个理由
  20. dz后台html,建立discuz后台管理页面的模板

热门文章

  1. 走进金融数据分析世界
  2. java的dispose方法_java-dispose()方法
  3. 二维不可压缩方腔驱动流数值解——基于涡量流函数方程
  4. 黄聪:Windows2012-IIS8安装SSL证书
  5. 黄聪:wordpress后台加载ajax.googleapis.com导致打开速度很慢的解决方案
  6. layui 省市区三级联动
  7. 使用javaparser分析重构java源码
  8. getElementById取不到,为什么呢?
  9. linux下的DNS域名解析全过程
  10. 程序员如何获得中级工程师高级工程师职称