Как остановить QElapsedTimer?

    QElapsedTimer timer;
    timer.start();

    slowOperation1();

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

http://doc.qt.io/qt-5/qelapsedtimer.html

После qDebug() Я хотел бы остановить этот таймер. Я не вижу ни функции остановки, ни свойства одиночного выстрела.

Какой выход?

3 ответа

Решение

Вы не можете остановиться QElapsedTimerпотому что нет таймера. Когда вы вызываете метод start(), QElapsedTimer сохраняет текущее время.

Из qelapsedtimer_generic.cpp

void QElapsedTimer::start() Q_DECL_NOTHROW
{
    restart();
}

qint64 QElapsedTimer::restart() Q_DECL_NOTHROW
{
    qint64 old = t1;
    t1 = QDateTime::currentMSecsSinceEpoch();
    t2 = 0;
    return t1 - old;
}

По истечении этого времени он снова получает текущее время и вычисляет разницу.

qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW
{
    return QDateTime::currentMSecsSinceEpoch() - t1;
}

PS Конкретная реализация зависит от платформы: Windows, Unix, Mac

Мне нужен истекший таймер, который не будет считать время паузы, поэтому вот что я придумал:ElapsedTimer.hpp:

      #pragma once

#include <time.h>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <errno.h>

namespace your_namespace {

class ElapsedTimer {
public:
    ElapsedTimer();
    ~ElapsedTimer();
    
    void Continue();
    void Pause();
    int64_t elapsed_ms();
    
private:
    struct timespec start_ = {};
    int64_t worked_time_ = 0;
    
    /// CLOCK_MONOTONIC_COARSE is faster but less precise
    /// CLOCK_MONOTONIC_RAW is slower but more precise
    const clockid_t clock_type_ = CLOCK_MONOTONIC_RAW;
};
}

ElapsedTimer.cpp:

      #include "ElapsedTimer.hpp"

namespace your_namespace {

ElapsedTimer::ElapsedTimer() {}
ElapsedTimer::~ElapsedTimer() {}

inline int64_t GetDiffMs(const timespec &end, const timespec &start) {
    return (end.tv_sec - start.tv_sec) * 1000L + (end.tv_nsec - start.tv_nsec) / 1000000L;
}

void ElapsedTimer::Continue()
{
    int status = clock_gettime(clock_type_, &start_);
    if (status != 0)
        printf("%s", strerror(errno));
}

int64_t ElapsedTimer::elapsed_ms()
{
    const bool paused = (start_.tv_sec == 0 && start_.tv_nsec == 0);
    if (paused)
        return worked_time_;
    
    struct timespec now;
    int status = clock_gettime(clock_type_, &now);
    if (status != 0)
        printf("%s", strerror(errno));
    
    const int64_t extra = GetDiffMs(now, start_);
    return worked_time_ + extra;
}

void ElapsedTimer::Pause() {
    struct timespec now;
    int status = clock_gettime(clock_type_, &now);
    if (status != 0)
        printf("%s", strerror(errno));
    
    worked_time_ += GetDiffMs(now, start_);
    start_ = {};
}
}

Для использования в качестве:

      my_namespace::ElapsedTimer timer;
timer.Continue(); // starts recording the amount of time
timer.Pause();// stops recording time
///do something else
timer.Continue();// resumes recording time
/// and at any time call this to find out how many
/// ms passed excluding the paused time:
int64_t passed_ms = timer.elapsed_ms();

QElapsedTimer будет использовать монотонные эталонные часы платформы на всех платформах, которые его поддерживают. Это имеет дополнительное преимущество, заключающееся в том, что QElapsedTimer невосприимчив к корректировкам времени, таким как корректировка времени пользователем. Также в отличие от QTime, QElapsedTimer невосприимчив к изменениям в настройках часового пояса, например, к переходу на летнее время. https://doc.qt.io/qt-5/qelapsedtimer.html

Другие вопросы по тегам