Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to emit a Qt signal daily at a given time?

Tags:

time

qt

I need to notify some objects to clear their cache at new day begins. So, I could create QTimer or something similar and check every ms that now midnight +-5ms or not, but it's not a good idea for me. Is there(in QT) any standard mechanisms to get notified about this event without allocating any new object? Something static or living since application's initialization like qApp? What would you do in situation like this where you need to do something at 00:00?

UPD: I'm looking for fast enough solution. Fast means that I need to clear container in slot as quick as it possible, 'cause since midnight data in the container become invalid. So, there is some other timer which shots every 100ms for instance and it trying to get data from container. I need to clear container with invalid data right before any possible try of getting access.

like image 880
cassandrad Avatar asked Mar 18 '14 14:03

cassandrad


1 Answers

The simplest solution does indeed utilize a timer. Polling for the passage of time in not only unnecessary, but would be horrible performance-wise. Simply start the actions when the midnight strikes:

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 some other timer which shots every 100ms for instance and it trying to get data from container.

Since both of these timers presumably run in the same thread, they execute serially and it doesn't matter how much "later" either one is. They won't both run at the same time.

like image 83
Kuba hasn't forgotten Monica Avatar answered Nov 15 '22 05:11

Kuba hasn't forgotten Monica