当接收器忙时,Qt信号会发生什么?

neu*_*rte 10 c++ qt multithreading qt-signals qtcore

在我的应用程序中,我有一个实例QTimer,其timeout()信号连接到主窗口对象中的一个插槽,导致它定期被调用.插槽用相机拍照并将其保存到磁盘.

我想知道QTimer当接收器(主线程上的窗口对象)当前正忙时(如同拍摄并保存前一张图片),如果发出信号(来自执行的单独线程,我推测)会发生什么.在前一个呼叫终止后,呼叫是否排队并执行?整个想法是让它定期运行,但这些调用可以排队,然后当控制返回到事件循环时随机调用,导致混乱吗?我怎么能避免呢?从理论上讲,插槽应该快速执行,但是假设硬件有一些问题并且存在停顿.

我希望在这种情况下调用被丢弃而不是排队,更有用的是能够在发生时作出反应(警告用户,终止执行).

Dig*_*ata 6

此时的其他答案都有相关的背景.但要知道的关键是,如果定时器回调是在不同线程中发信号通知槽,则该连接是QueuedConnection或BlockingQueuedConnection.

因此,如果您正在使用计时器尝试进行某种常规处理,那么这会在计时器触发和插槽实际执行之间的时间间隔给您一些额外的抖动,因为接收对象在它自己的线程中运行独立的事件循环.这意味着当事件放入队列时它可以执行任意数量的其他任务,直到它完成处理这些事件,图片线程将不会执行您的计时器事件.

计时器应与照片逻辑位于同一个线程中.将计时器放在与摄像机拍摄相同的线程中,可以直接连接,并在定时间隔内提供更好的稳定性.特别是如果照片捕获和保存偶尔会有特殊的持续时间.

它是这样的,假设间隔是10秒:

  • 设定计时器10秒钟
  • 计时器开火
  • 节省开始时间
  • 拍照
  • 将照片保存到磁盘(因为某些奇怪的原因需要3秒)
  • 计算10-(当前时间 - 开始时间)= 7秒
  • 设定时间为7秒

您还可以在此处设置一些逻辑来检测跳过的间隔(例如,其中一个操作需要11秒才能完成...

  • +1 ;-)我做了[一些实验](http://stackoverflow.com/a/18692409/1951907).如果失速超过定时器间隔的两倍(即错过两次或更多次点击),则确实是对的.否则,如果只能错过一次点击(这是我一直在进行的情况),计时器会正确赶上.因此,如果您对失速可能需要多长时间没有上限(显然是OP的情况),那么您的解决方案是正确的. (2认同)