如何在给定时间每天发出 Qt 信号? [英] How to emit a Qt signal daily at a given time?

查看:46
本文介绍了如何在给定时间每天发出 Qt 信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在新的一天开始时通知一些对象清除它们的缓存.所以,我可以创建 QTimer 或类似的东西,并检查现在午夜 +-5ms 的每个毫秒,但这对我来说不是一个好主意.是否(在 QT 中)有任何标准机制可以在不分配任何新对象的情况下获得有关此事件的通知?自应用程序初始化后,像 qApp 一样是静态的还是活跃的?在这种情况下,您需要在 00:00 做某事,您会怎么做?

更新:我正在寻找足够快的解决方案.快速意味着我需要尽可能快地清除插槽中的容器,因为从容器中的午夜数据开始无效.因此,还有一些其他计时器每 100 毫秒触发一次,并尝试从容器中获取数据.我需要在任何可能的访问尝试之前清除包含无效数据的容器.

解决方案

最简单的解决方案确实使用了计时器.轮询时间的流逝不仅是不必要的,而且在性能方面也会很糟糕.只需在午夜来临时开始行动:

static int msecsTo(const QTime & at) {const int msecsPerDay = 24 * 60 * 60 * 1000;int msecs = QTime::currentTime().msecsTo(at);if (msecs <0) msecs += msecsPerDay;返回毫秒;}//C++11void runAt(const std::function & job, const QTime & at, Qt::TimerType type = Qt::VeryCoarseTimer) {//计时器所有权可防止线程终止时计时器泄漏.自动计时器 = new QTimer(QAbstractEventDispatcher::instance());计时器->开始(毫秒到(at),类型);QObject::connect(timer, &QTimer::timeout, [=job, &timer]{工作();定时器->deleteLater();});}runAt([&]{ object->member(); }, QTime(...));//C++98void scheduleSlotAt(QObject * obj, const char * member, const QTime & at, Qt::TimerType type = Qt::VeryCoarseTimer) {QTimer::singleShot(msecsTo(at), type, obj, member);}类 MyObject : 公共 QObject {Q_OBJECTvoid scheduleCleanup() {scheduleSlotAt(this, SLOT(atMidnight()), QTime(0, 0));}Q_SLOT void atMidnight() {//在这里做一些工作...计划清理();}民众:MyObject(QObject * parent = 0) : QObject(parent) {...计划清理();}};

<块引用>

例如,还有一些其他计时器每 100 毫秒触发一次,并尝试从容器中获取数据.

因为这两个计时器大概在同一个线程中运行,所以它们是串行执行的,并且无论稍后"多少时间都没有关系.它们不会同时运行.

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.

解决方案

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.

这篇关于如何在给定时间每天发出 Qt 信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆