How to emit a Qt signal daily at a specific point in time?

I need to notify some objects in order to clear their cache on a new day. That way, I could create a QTimer or something similar and check every ms that it’s now midnight + -5 ms or not, but this is not a good idea for me. Are there (in QT) any standard mechanisms for receiving notification of this event without allocating any new object? Something static or live since the application was initialized, for example qApp? What would you do in a situation where you need to do something at 00:00?

UPD: I'm looking for a fairly quick solution. Fast means that I need to clear the container in the slot as quickly as possible, because since the data at midnight in the container becomes invalid. So, there is another timer that takes every 100 ms, for example, and tries to get data from the container. I need to clear the container with invalid data right before any attempt to gain access.

+4
source share
1 answer

The simplest solution really uses a timer. A survey over time is not only unnecessary, but will be terrible in performance. Just start the action when it is midnight:

static int msecsTo(const QTime & at) {
  const int msecsPerDay = 24 * 60 * 60 * 1000;
  int msecs = QTime::currentTime().msecsTo(at);
  if (msecs < 0) msecs += msecsPerDay;
  return msecs;
}

// C++11

void runAt(const std::function<void> & job, const QTime & at, Qt::TimerType type = Qt::VeryCoarseTimer) {
  // Timer ownership prevents timer leak when the thread terminates.
  auto timer = new QTimer(QAbstractEventDispatcher::instance());
  timer->start(msecsTo(at), type);
  QObject::connect(timer, &QTimer::timeout, [=job, &timer]{
    job();
    timer->deleteLater();
  });
}  

runAt([&]{ object->member(); }, QTime(...));

// C++98

void scheduleSlotAt(QObject * obj, const char * member, const QTime & at, Qt::TimerType type = Qt::VeryCoarseTimer) {
  QTimer::singleShot(msecsTo(at), type, obj, member);
}

class MyObject : public QObject {
  Q_OBJECT
  void scheduleCleanup() {
    scheduleSlotAt(this, SLOT(atMidnight()), QTime(0, 0));
  }
  Q_SLOT void atMidnight() {
    // do some work here
    ...
    scheduleCleanup();
  }
public:
  MyObject(QObject * parent = 0) : QObject(parent) {
    ...
    scheduleCleanup();
  }
};  

there is another timer that takes off every 100 ms, for example, and tries to get data from the container.

, , , "" - . .

+9

Source: https://habr.com/ru/post/1532309/


All Articles