简体   繁体   English

Qt:使用QEventLoop等待信号,如果信号发得太早怎么办?

[英]Qt: Waiting for a signal using QEventLoop, what if the signal is emitted too early?

I am working on an small client-server application. 我正在开发一个小型客户端 - 服务器应用程序。 The client sends a query and has to wait for an answer. 客户端发送查询并且必须等待答复。 I think the most convenient way is to use a QEventLoop: 我认为最方便的方法是使用QEventLoop:

connect(&parser, SIGNAL(answer_received()), this, SLOT(react_to_answer()));
...
...
QEventLoop loop;
connect(&parser, SIGNAL(answer_received()), &loop, SLOT(quit()));
this.sendQuery();
loop.exec();

This worked for me at the moment, but what happens, if the signal answer_received() is emitted very fast, even before loop.exec() was called? 这对我来说当前answer_received() ,但是如果answer_received()速度非常快,甚至在loop.exec()之前会loop.exec()什么呢? Will my application stuck in the QEventLoop forever? 我的应用程序会永远停留在QEventLoop中吗?

Thank you! 谢谢!

Given your code, the only way you will encounter an issue is if the answer_received() signal is emitted before loop.exec() is called. 鉴于你的代码,你会遇到的一个问题是,如果唯一的办法answer_received()信号发出之前loop.exec()被调用。 Which is equivalent to say that answer_received() is emitted during the call to this.sendQuery(); 这相当于说, answer_received()调用过程中发出this.sendQuery(); .

In your case it is not likely to happen because you rely on server/client interactions and you likely use a QNetworkAccessManager or a QSocket of some sort. 在您的情况下,它不太可能发生,因为您依赖于服务器/客户端交互,并且您可能使用某种QNetworkAccessManagerQSocket If this is the case the QNetworkAccessManager/QSocket will not emit readyRead() or finished() signals until you enter the event loop. 如果是这种情况,QNetworkAccessManager / QSocket将不会发出readyRead()finished()信号,直到您进入事件循环。

However, in a more general case if answer_received() can be emitted from this.sendQuery() you have to change your code: 然而,如果一个更一般的情况下answer_received()可以从发射this.sendQuery()你必须改变你的代码:

  1. You could make the connection between to be queued. 您可以使它们之间的连接排队。 This way even if answer_received() is emitted during this.sendQuery() the slot will not be called until you enter the event loop. 这种方式即使在answer_received()期间发出this.sendQuery()在您进入事件循环之前也不会调用插槽。

     connect(&parser, SIGNAL(answer_received()), &loop, SLOT(quit()), Qt::QueuedConnection); 
  2. You could ensure that answer_received() is never emitted during this.sendQuery() . 您可以确保在answer_received()期间永远不会发出this.sendQuery() On way to do so is to use 0ms QTimer, which will trigger as soon as all events in the event queue are processed, ie during loop.exec() 在这样做的方法是使用0ms QTimer,它将在事件队列中的所有事件处理后立即触发,即在loop.exec()期间

    Replace: 更换:

     emit answer_received(); 

    By: 通过:

     QTimer::singleShot(0, this, *receiver, &MyClass::answer_received); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM