Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多个延迟的QTimer::singleShot调用会立即触发所有插槽_Qt_Qtimer - Fatal编程技术网

多个延迟的QTimer::singleShot调用会立即触发所有插槽

多个延迟的QTimer::singleShot调用会立即触发所有插槽,qt,qtimer,Qt,Qtimer,我有>1个服务,我想用它在函数“performCheck(…)”中做点什么。对于每个服务,第一次调用performCheck函数时应延迟1s。但是,如果我有例如3个服务(_服务),则会立即为所有3个服务调用performCheck,而不是延迟 有人知道为什么会同时发生这种情况吗(我(目前)只有运行QTimer的主QThread) 示例代码: int timeoutMs = 0; for(auto& serviceContainer : _services) { Q_DEBUG_M

我有>1个服务,我想用它在函数“performCheck(…)”中做点什么。对于每个服务,第一次调用performCheck函数时应延迟1s。但是,如果我有例如3个服务(_服务),则会立即为所有3个服务调用performCheck,而不是延迟

有人知道为什么会同时发生这种情况吗(我(目前)只有运行QTimer的主QThread)

示例代码:

int timeoutMs = 0;
for(auto& serviceContainer : _services) {
    Q_DEBUG_M() << "Perform check for " << serviceContainer.service->getServiceTypeDescription() << " in " << timeoutMs << "ms";

    serviceContainer.checkOngoing = true;
    QTimer::singleShot(timeoutMs, this, [this, &serviceContainer]() {
        performCheck(serviceContainer);
    });
    timeoutMs+=1000;
}
int timeoutMs=0;
对于(自动和服务容器:_服务){

Q_DEBUG_M()正如您在评论和问题中指出的,它取决于事件队列(EventLoop)。 当一个
QTimer
超时时(无论是单次触发还是普通计时器),触发的插槽将被推送到事件队列并进行处理。现在,由于您只有一个主线程在运行,因此您只有一个事件队列(如果事件队列被阻止,QTimer也将触发)

现在在您的例子中,想象一些东西用一些东西阻塞主线程(比如QML东西的init)超过3秒。因此,您的事件队列停止超过3秒。但QTimer很高兴地推动队列中要触发的插槽。现在,在解除阻止线程后,事件队列处理将继续,它将“立即”处理QTimer推动的所有插槽


一个简单的解决方案是你在init之后执行你的检查。如果对你有用的话,那就好了。否则考虑通过<代码> QTox编写服务的异步检查。一个Q线程有它自己的事件循环(队列)。。因此,您可以按时执行检查并报告结果,当主线程再次响应时将获取结果。我希望这能为您澄清问题。

正如您在评论和问题中指出的,它取决于EventQueue(EventLoop)。 当一个
QTimer
超时时(无论是单次触发还是普通计时器),触发的插槽将被推送到事件队列并进行处理。现在,由于您只有一个主线程在运行,因此您只有一个事件队列(如果事件队列被阻止,QTimer也将触发)

现在在您的例子中,想象一些东西用一些东西阻塞主线程(比如QML东西的init)超过3秒。因此,您的事件队列停止超过3秒。但QTimer很高兴地推动队列中要触发的插槽。现在,在解除阻止线程后,事件队列处理将继续,它将“立即”处理QTimer推动的所有插槽


一个简单的解决方案是你在init之后执行你的检查。如果对你有用的话,那就好了。否则考虑通过<代码> QTox编写服务的异步检查。一个Q线程有它自己的事件循环(队列)。。因此,您可以及时执行检查并报告结果,当主线程再次响应时将获取结果。我希望这能为您解决问题。

您确定所有回调都会立即触发吗?我希望在您返回事件循环时会调用第一个回调(超时时间为零)但不是剩下的。如果可能的话,请提供一个。因此,它现在可以工作了。基本上,我们的应用程序是安静的,需要一点初始化一切在开始(GUI应用程序)。我很早就在构造函数中调用了上述代码,然后注册了所有QML类型,等等。如果我在注册了所有QML类型等之后调用了上述代码,那么它将以正确的延迟开始,而不是一次调用所有代码(尽管设置了延迟)因此,我认为,事件队列在这一点上没有被初始化。我将对它进行更深入的研究,但是在初始化过程中稍稍移动上面代码的调用似乎可以解决这个问题。请在考虑到它对你有帮助的时候,考虑一下投票并接受一个答案。立即红色?我希望在您返回事件循环(它有零超时)时第一个会被调用,但其余的不会。如果可能,请提供一个。因此,它现在可以工作了。基本上,我们的应用程序是安静的,需要一点时间在开始时初始化所有内容(GUI应用程序)。我很早就在构造函数中调用了上述代码,然后注册了所有QML类型,等等。如果我在注册了所有QML类型等之后调用了上述代码,那么它将以正确的延迟开始,而不是一次调用所有代码(尽管设置了延迟)因此,我认为,事件队列在这一点上没有被初始化。我将对它进行更深入的研究,但是在初始化过程中稍稍移动上面代码的调用似乎可以解决这个问题。请在考虑到它对您有帮助并回答您的问题时,考虑接受和接受答案。