在我的应用程序中,我有一个QTimer实例,其timeout()信号连接到主窗口对象中的一个插槽,导致定期调用.插槽用相机拍摄照片并将其保存到磁盘.
我想知道当接收机(主线程上的窗口对象)当前正在忙碌时(如同拍摄和保存上一张图片),如果发出信号(从QTimer执行的单独线程,我假定)会发生什么情况.在上一次呼叫结束后,呼叫是否排队等待执行?整个想法是让它定期运行,但是这些调用可以排队,然后在控件返回到事件循环时随机调用,从而导致混乱?我该如何避免呢?理论上,这个插槽应该很快执行,但是我们说硬件有一些问题,有一个停顿.
我希望在这种情况下,呼叫被丢弃而不是排队,更有用的是在发生时作出反应的能力(警告用户,终止执行).
解决方法
此时其他答案有相关背景.但是要解决的关键是如果定时器回调信号是在不同线程中发送一个插槽,则该连接是QueuedConnection或BlockingQueuedConnection.
因此,如果您使用定时器尝试并进行某种常规处理,那么这会给定时器在定时器触发之间的时间和插槽实际执行之间的额外抖动,因为接收对象在其自己的线程中运行一个独立的事件循环.这意味着当事件放在队列中,直到它完成处理这些事件之后,它可能会执行任何其他任务,图片线程将不会执行您的定时器事件.
定时器应该在与照片逻辑相同的线程中.将定时器放在与相机拍摄的线程相同的线程中,直接连接,并在您的时间间隔内给予更好的稳定性.特别是如果照片捕获&保存偶尔有特殊的持续时间.
它是这样的,假设间隔是10秒:
>设置定时器10秒
>定时器触发
>保存开始时间
>拍照
>将照片保存到磁盘(说出一些奇怪的原因需要3秒钟)
>计算10-(当前时间 – 开始时间)=七秒
>设置超时七秒钟
您也可以在这里设置一些逻辑来检测跳过的间隔(说操作需要11秒才能完成…