[英]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. 在您的情况下,它不太可能发生,因为您依赖于服务器/客户端交互,并且您可能使用某种
QNetworkAccessManager
或QSocket
。 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()
你必须改变你的代码:
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);
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.