Как остановить 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
сохраняет текущее время.
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