【问题标题】:QTimer timeout processing when Qt main event queue is blockedQt主事件队列阻塞时的QTimer超时处理
【发布时间】:2015-06-25 16:52:09
【问题描述】:

如果我启动 QTimer 以固定间隔触发,但插槽对超时信号作出反应,会比另一个计时器间隔更长时间地阻塞主循环。是否会在事件循环再次运行时将 timout 信号堆叠在 Qt 主事件循环上并一个接一个地处理?

如果是,如果多个超时事件堆叠在事件队列上,但计时器在处理之前被停用,会发生什么情况?

【问题讨论】:

    标签: qt events timer


    【解决方案1】:

    如果QTimer 对象和信号接收器属于一个线程,则不会发生排队。 timeout() 信号在控制流进入事件循环之前不会(也不能)再次发送,并且直到插槽完全执行后才会发生(除非在插槽中调用QApplication::processEvents,这可以将其变成一团糟)。但是,如果您的插槽执行时间超过计时器的时间间隔,一旦事件循环空闲,timeout() 将被发送,因此您的插槽将立即再次被调用。但是QTimer 不会发送两个比其间隔更近的timeout() 信号。

    如果QTimer 在另一个线程中,并且该线程没有忙于其他事情,它会定期发送timeout() 信号,而不管另一个线程中的槽有多好。这就是 Qt 的信号槽系统的用武之地。它将对发出的信号进行排队。如果您的插槽很慢,它会毫不拖延地多次调用它。如果您停止计时器,它不会撤消已发送的信号,并且可能会在它之后多次调用插槽。此外,如果您停止计时器,则总是有可能此时正在发送另一个信号,并且您的插槽将再次被调用。

    如果您希望在插槽调用之间有严格的间隔,而不管插槽的执行时间如何,您应该使用单次计时器。在您的插槽结束时,启动一个单次计时器。当它超时时,它将调用您的插槽并停用,因此您可以在插槽结束时再次启动它。

    如果您的程序逻辑取决于计时器的状态,您应该检查计时器在您的槽开始时是否处于活动状态。不保证在执行槽时计时器处于活动状态。

    【讨论】:

      猜你喜欢
      • 2011-03-27
      • 2017-09-13
      • 2019-07-06
      • 1970-01-01
      • 2014-10-16
      • 1970-01-01
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      相关资源
      最近更新 更多