我正在开发一个小型客户端 - 服务器应用程序。客户端发送查询并且必须等待答复。我认为最方便的方法是使用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();
目前这对我有用,但是如果信号answer_received()
发出的速度非常快,甚至在调用loop.exec()
之前会发生什么?我的申请会永远停留在QEventLoop吗?
谢谢!
答案 0 :(得分:4)
鉴于您的代码,您遇到问题的唯一方法是在调用answer_received()
之前发出loop.exec()
信号。这相当于在调用answer_received()
期间发出this.sendQuery();
。
在您的情况下,由于您依赖服务器/客户端交互并且您可能使用某种QNetworkAccessManager
或QSocket
,因此不太可能发生这种情况。如果是这种情况,QNetworkAccessManager / QSocket将不会发出readyRead()
或finished()
信号,直到您进入事件循环。
但是,在更一般的情况下,如果answer_received()
可以从this.sendQuery()
发出,则必须更改代码:
您可以在排队之间建立连接。这种方式即使在answer_received()
期间发出this.sendQuery()
,在您进入事件循环之前也不会调用该插槽。
connect(&parser, SIGNAL(answer_received()), &loop, SLOT(quit()), Qt::QueuedConnection);
您可以确保answer_received()
期间永远不会发出this.sendQuery()
。在这样做的方法是使用0ms QTimer,它将在事件队列中的所有事件被处理后立即触发,即在loop.exec()
期间
替换:
emit answer_received();
人:
QTimer::singleShot(0, this, *receiver, &MyClass::answer_received);