The most accurate timer qt C++

有些话、适合烂在心里 提交于 2019-12-20 08:07:16

问题


I use QTimer to send periodically 'Ping' packet to the server (MQTT client). But it timer is not absolutely accurate. After some time of working it has some delay and server broken connection. I try to use different Qt::TimerType, but it does not help. I need the most accurate timer. Do you have any ideas?

Thank you!


EDIT (Frederik solution)


I have done something this:

tthread.h

class TThread : public QThread
{
    Q_OBJECT

    void run();

public:
    explicit TThread(QObject *parent = 0);

signals:

private slots:
    void timerOut();
};

tthread.cpp

TThread::TThread(QObject *parent) : QThread(parent)
{

}

void TThread::run()
{
    QTimer timer;
    connect(&timer, SIGNAL(timeout()), this, SLOT(timerOut()), Qt::DirectConnection);
    timer.start(1000);
    timer.moveToThread(this);
    exec();
}

void TThread::timerOut()
{
    QTime time = QTime();
    qDebug() << time.currentTime().toString();
}

main.cpp

TThread thread;
thread.start();
thread.setPriority(QThread::HighPriority);

回答1:


Run a QTimer on a separate QThread which doesn't do anything else. If you're running the timer on an already busy thread the timeout events may not come on time or not at all.

Make a worker class e.g. "PingPacketWorker", implement a slot that does pinging. Make a QThread. Connect your QTimer and PingPacketWorker signal/slots. Start the timer. Call moveToThread on the PingPacketWorker and the QTimer, the timer should restart because of moveToThread, note you can only start / stop it on the owner thread!

You could also increase your QThread's priority since you asked for "the most accurate" solution ...

Update:

Also, set QTimer::setTimerType(Qt::PreciseTimer)

The default Qt::CoarseTimer is less precise (5% of the interval)




回答2:


#pragma once

#include <cstdint>
#include <QObject>

class PrecisePolling : public QObject
{
    Q_OBJECT
private:
    std::uint64_t previousPollingTime;
public:
    PrecisePolling();

public slots:
    void doPolling();

#include "precisepolling.h"
#include "QDateTime"
#include <QDebug>

PrecisePolling::PrecisePolling()
    : previousPollingTime(QDateTime::currentMSecsSinceEpoch())
{}

void PrecisePolling::doPolling()
{
    const std::uint64_t ms = QDateTime::currentMSecsSinceEpoch();
    qDebug() << ms - previousPollingTime;
    previousPollingTime = ms;
}

#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include "precisepolling.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QThread thread;
    QTimer timer;
    PrecisePolling pp;

    timer.setInterval(1000);
    timer.setTimerType(Qt::PreciseTimer);

    QObject::connect(&timer, &QTimer::timeout, &pp, &PrecisePolling::doPolling);
    timer.start();
    timer.moveToThread(&thread);
    pp.moveToThread(&thread);

    thread.start(QThread::Priority::TimeCriticalPriority);

    return a.exec();
}


来源:https://stackoverflow.com/questions/51927666/the-most-accurate-timer-qt-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!