QElapsedTimer 类

QElapsedTimer 类提供了一种快速计算经过时间的方法。 更多信息...

头文件 #include <QElapsedTimer>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core

注意:本类中所有函数均为可重入

公共类型

枚举ClockType { 系统时间, 单调时钟, 计数器, Mach 绝对时间, 性能计数器 }
持续时间
时间点

公共函数

QElapsedTimer()
(自 6.6) QElapsedTimer::DurationdurationElapsed() const
(自 6.6) QElapsedTimer::DurationdurationTo(const QElapsedTimer &other) const
qint64elapsed() const
boolhasExpired(qint64 timeout) const
voidinvalidate()
boolisValid() const
qint64msecsSinceReference() const
qint64msecsTo(const QElapsedTimer &other) const
qint64nsecsElapsed() const
qint64restart()
qint64secsTo(const QElapsedTimer &other) const
voidstart()

静态公共成员

QElapsedTimer::ClockTypeclockType()
boolisMonotonic()
booloperator!=(const QElapsedTimer &lhs, const QElapsedTimer &rhs)
booloperator==(const QElapsedTimer &lhs, const QElapsedTimer &rhs)

详细描述

QElapsedTimer 类通常用于快速计算两个事件之间经过的时间。它的 API 与 QTime 类似,因此可以使用旧代码快速迁移到新类。

然而,与 QTime 不同,QElapsedTimer 尝试在可能的情况下使用单调时钟。这意味着无法将 QElapsedTimer 对象转换为人类可读的时间。

该类的典型用例是确定耗时操作花费了多少时间。这样一个用例的最简单例子是用于调试目的,如下面的示例所示

    QElapsedTimer timer;
    timer.start();

    slowOperation1();

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

在这个例子中,通过调用 start() 方法启动计时器,并通过elapsed() 函数计算已过时间。

可以也使用已过的时间来重新计算在第一个操作完成后可用于另一个操作的时间。当执行必须在一个特定的时间段内完成,但需要多个步骤时,这是很有用的。在 QIODevice 和它的子类中的 waitFor-type 函数是这种需求的良好示例。在这种情况下,代码可能如下所示

void executeSlowOperations(int timeout)
{
    QElapsedTimer timer;
    timer.start();
    slowOperation1();

    int remainingTime = timeout - timer.elapsed();
    if (remainingTime > 0)
        slowOperation2(remainingTime);
}

另一个用例是执行特定时间段内的某个操作。为此,QElapsedTimer 提供了一个便利函数hasExpired(),可以用来判断是否已经过了一定的毫秒数。

void executeOperationsForTime(int ms)
{
    QElapsedTimer timer;
    timer.start();

    while (!timer.hasExpired(ms))
        slowOperation1();
}

在这种情况下,使用 QDeadlineTimer 通常更方便,它不是跟踪已过时间,而是在未来计算超时。

参考时钟

在所有支持该功能的平台上,QElapsedTimer 将使用平台的单调参考时钟(参见QElapsedTimer::isMonotonic())。这还有一个额外的好处,即 QElapsedTimer 对时间调整免疫,例如用户更正时间。与 QTime 不同,QElapsedTimer 也能抵御时区设置变化,例如夏令时。

另一方面,这意味着 QElapsedTimer 的值只能与使用相同参考的其他值进行比较。这尤其适用于从[qelapsedtimer.html#msecsSinceReference" translate="no">QElapsedTimer)对象中提取自参考的时间,并将其序列化。这些值永远不应该在网络中交换或将它们保存到磁盘上,因为无法确定接收数据的计算机节点与原节点是否相同,或者它是否在这之后重新启动了。

然而,如果其他在相同机器上运行的过程也使用相同的参考时钟,则可以与其他进程交换值。QElapsedTimer 总是使用相同的时钟,所以可以安全地将其值与其他来自相同机器的进程进行比较。如果将出现在其他 API 生成的值进行比较,则应检查使用的时钟是否与 QElapsedTimer 的相同(参见QElapsedTimer::clockType())。

另请参阅QTimeQTimerQDeadlineTimer

成员类型文档

枚举 QElapsedTimer::ClockType

此枚举包含 QElapsedTimer 可能使用的不同时钟类型。

在特定机器上,QElapsedTimer 总是使用相同的时钟类型,所以这个值在整个程序的生命周期中不会改变。这是为了提供QElapsedTimer 用于与其他非 Qt 实现一起使用,以确保使用了相同的参考时钟。

常量描述
QElapsedTimer::SystemTime0可读性系统时间。此时钟不是单调的。
QElapsedTimer::MonotonicClock1系统的单调时钟,通常在 Unix 系统中找到。此时钟是单调的。
QElapsedTimer::TickCounter2不再使用。
QElapsedTimer::MachAbsoluteTime3MacOS 和 iOS 的 Mach 内核的绝对时间。此时钟是单调的。
QElapsedTimer::PerformanceCounter4Windows 提供的性能计数器。此时钟是单调的。
SystemTime

系统时间计时器完全是实际时间,以自1970年1月1日0:00 UTC以来的毫秒表示。这与C和POSIX中的time函数返回的值相同,只是增加了毫秒。此时钟类型目前仅在不支持单调时钟的Unix系统上使用(见下文)。

这是QElapsedTimer可能使用的唯一非单调时钟。

单调钟

这是系统的单调时钟,以自过去任意点以来的毫秒表示。此时钟类型用于支持POSIX单调时钟的Unix系统(_POSIX_MONOTONIC_CLOCK)。

Mach绝对时间

此时钟类型基于Mach内核提供的绝对时间,例如在macOS中找到的那样。鉴于macOS和iOS也是Unix系统并且可能支持与Mach绝对时间不同的POSIX单调时钟,此时钟类型与MonotonicClock分开表示。

此钟是单调的。

性能计数器

此时钟使用Windows函数QueryPerformanceCounterQueryPerformanceFrequency来访问系统的性能计数器。

此钟是单调的。

另请参阅 clockType()和isMonotonic

[别名] QElapsedTimer::Duration

std::chrono::nanoseconds的同义词。

[别名] QElapsedTimer::TimePoint

std::chrono::time_point的同义词。

成员函数文档

[constexpr noexcept] QElapsedTimer::QElapsedTimer()

构造一个无效的QElapsedTimer。定时器一旦启动即变为有效。

另请参阅 isValid()和start

[static noexcept] QElapsedTimer::ClockType QElapsedTimer::clockType()

返回此QElapsedTimer实现使用的时钟类型。

自Qt 6.6以来,QElapsedTimer使用std::chrono::steady_clock,因此时钟类型始终为MonotonicClock

另请参阅 isMonotonic

[noexcept, since 6.6] QElapsedTimer::Duration QElapsedTimer::durationElapsed() const

返回自QElapsedTimer上次启动以来时间的std::chrono::nanoseconds

在无效的QElapsedTimer上调用此函数将导致未定义的行为。

在不提供纳秒分辨率的平台上,返回的值将是可用的最佳估计。

此函数是在Qt 6.6中引入的。

另请参阅 startrestarthasExpiredinvalidate

[noExcept, since 6.6] QElapsedTimer::Duration QElapsedTimer::durationTo(const QElapsedTimer &other) const

返回这个QElapsedTimerother之间的时间差,以std::chrono::nanoseconds表示。如果other在当前对象之前启动,返回的值将是负数。如果它晚于当前对象启动,返回的值将是正数。

如果这个对象或other无效,则返回值未定义。

此函数是在Qt 6.6中引入的。

另请参阅secsTo()和elapsed

[noexcept] qint64 QElapsedTimer::elapsed() const

返回自QElapsedTimer上次启动以来的毫秒数。

在无效的QElapsedTimer上调用此函数将导致未定义的行为。

另请参阅start(),restart(),hasExpired(),isValid()和invalidate

[noexcept] bool QElapsedTimer::hasExpired(qint64 timeout) const

如果elapsed()超过给定的timeout,则返回true,否则返回false

一个负的timeout被解释为无限期,所以在这个情况下返回false。否则,这等同于elapsed() > timeout。您可以通过将durationElapsed()与持续时间超时值进行比较来进行相同操作。

另请参阅elapsed()和QDeadlineTimer

[noexcept] void QElapsedTimer::invalidate()

将该QElapsedTimer对象标记为无效。

可以通过isValid()来检查无效的对象。自上次无效数据以来,计时器的经过时间计算是未定义的,并可能产生奇怪的结果。

另请参阅isValidstartrestart

[static noexcept] bool QElapsedTimer::isMonotonic()

如果这是一个单调时钟,则返回true,否则返回false。请参阅不同时钟类型的信息,了解哪种是单调的。

从Qt 6.6开始,QElapsedTimer使用std::chrono::steady_clock,因此此函数现在始终返回true。

另请参阅clockType()和QElapsedTimer::ClockType

[noexcept] bool QElapsedTimer::isValid() const

如果计时器从未被启动或被invalidate()调用使无效,则返回false

另请参阅invalidatestartrestart

[noexcept] qint64 QElapsedTimer::msecsSinceReference() const

返回自上次启动此QElapsedTimer对象至其参考时钟的启动之间的毫秒数。

这个数字通常是除了QElapsedTimer::SystemTime时钟之外的所有时钟的任意值。对于这种时钟类型,这个数字是从1970年1月1日0:00 UTC以来经过的毫秒数(即以毫秒表示的Unix时间)。

在Linux、Windows和Apple平台上,这个值通常是自系统启动以来的时间,尽管通常不包括系统休眠状态所花费的时间。

另请参见 clockType()和elapsed()。

[noexcept] qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const

返回此QElapsedTimerother之间的毫秒数。如果other在此次对象启动之前启动,返回的值将为负。如果在之后启动,返回的值将为正。

如果这个对象或other无效,则返回值未定义。

另请参阅secsTo()和elapsed

[noexcept] qint64 QElapsedTimer::nsecsElapsed() const

返回自此QElapsedTimer上次启动以来的纳秒数。

在无效的QElapsedTimer上调用此函数将导致未定义的行为。

在不提供纳秒分辨率的平台上,返回的值将是可用的最佳估计。

另请参阅 startrestarthasExpiredinvalidate

[noexcept] qint64 QElapsedTimer::restart()

重新启动计时器并返回上一次启动以来经过的毫秒数。此函数相当于用elapsed()获取经过的时间,然后再次用start()启动计时器,但它在一个单独的操作中完成,避免了需要两次获取时钟值的需要。

在无效的QElapsedTimer上调用此函数将导致未定义的行为。

以下示例说明了如何使用此函数校准一个慢速操作(例如,迭代次数)的参数,以便此操作至少要花费250毫秒。

    QElapsedTimer timer;

    int count = 1;
    timer.start();
    do {
        count *= 2;
        slowOperation2(count);
    } while (timer.restart() < 250);

    return count;

另请参见 start()、invalidate()、elapsed()和isValid()。

[noexcept] qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const

返回此QElapsedTimerother之间的秒数。如果other在此次对象启动之前启动,返回的值将为负。如果在之后启动,返回的值将为正。

在一个无效的QElapsedTimer上或与此QElapsedTimer一起调用此函数将产生未定义行为。

另请参见 msecsTo()和elapsed()。

[noexcept] void QElapsedTimer::start()

启动此计时器。一旦启动,就可以用elapsed()或msecsSinceReference()检查计时器的值。

通常,在耗时操作(例如)之前启动计时器。

    QElapsedTimer timer;
    timer.start();

    slowOperation1();

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

此外,启动计时器也会使其再次有效。

另请参阅 restart(),invalidate() 和 elapsed()。

相关非成员

[noexcept] bool operator!=(const QElapsedTimer &lhs, const QElapsedTimer &rhs)

如果 lhsrhs 包含不同的时间,则返回 true,否则返回 false

[noexcept] bool operator==(const QElapsedTimer &lhs, const QElapsedTimer &rhs)

如果 lhsrhs 包含相同的时间,则返回 true,否则返回 false

© 2024 The Qt Company Ltd. 本文件中包含的文档贡献为其各自所有者的版权。本文件中提供的文档根据自由软件基金会发布的 GNU自由文档许可证版本1.3 的条款进行许可。Qt及其相关标志是The Qt Company Ltd在芬兰和其他国家/地区的商标。所有其他商标均为其各自所有者的财产。