Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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? Will my application stuck in the QEventLoop forever?

Thank you!

like image 933
Horst Avatar asked Sep 06 '25 03:09

Horst


1 Answers

Given your code, the only way you will encounter an issue is if the answer_received() signal is emitted before loop.exec() is called. Which is equivalent to say that answer_received() is emitted during the call to 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. If this is the case the QNetworkAccessManager/QSocket will not emit readyRead() or finished() signals until you enter the event loop.

However, in a more general case if answer_received() can be emitted from this.sendQuery() you have to change your code:

  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.

    connect(&parser, SIGNAL(answer_received()), &loop, SLOT(quit()), Qt::QueuedConnection);
    
  2. You could ensure that answer_received() is never emitted during 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, i.e during loop.exec()

    Replace:

    emit answer_received();
    

    By:

    QTimer::singleShot(0, this, *receiver, &MyClass::answer_received);
    
like image 65
Benjamin T Avatar answered Sep 07 '25 22:09

Benjamin T