I am writing an application that interacts with the database. Since queries to the database are relatively heavy, I thought about moving the code into separate threads so as not to “freeze” the user interface.

In addition to queries to the database, this code also performs requests to the remote web server via the network. All anything, but QNetworkAccessManager does not provide methods that block the execution context at the time of sending requests and receiving answers to them. This feature leads to the need to organize a more complex code model. We'll have to combine asynchrony (work with the network) with multithreading (in fact, queries to the database).

The flow operation order:

  1. query to the database;
  2. based on the data received, the request to the network;
  3. based on the data retrieved, query to the database.

How to implement the combination of asynchrony with multithreading in the simplest way without using cumbersome constructions, such as inheritance from QThread and using its event loop?

  • You can query and receive a QNetworkAccessManager response in one function. I had the code on the example of working with QWebView. Actions: sent a request, created QEventLoop and hung the finished signal on loop.quit, then started the loop. And when the page was loaded and the answer came, there was a exit from eventLoop. An example is in the wait_loading function . - gil9red
  • Thank. Issue as an answer, please. - alexis031182

1 answer 1

The example below makes asynchronous QNetworkAccessManager synchronous using QEventLoop . QNetworkAccessManager signs the finished signal on the QEventLoop :: quit slot, executes an asynchronous get request and starts QEventLoop, which “spins” until the finished signal arrives:

 #include <QNetworkAccessManager> #include <QEventLoop> #include <QDebug> #include <QNetworkReply> #include <QNetworkProxyFactory> int main(int argc, char *argv[]) { QApplication a(argc, argv); QNetworkProxyFactory::setUseSystemConfiguration(true); QNetworkAccessManager nam; QEventLoop loop; QObject::connect(&nam, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit())); QNetworkReply *reply = nam.get(QNetworkRequest(QUrl("http://google.com"))); loop.exec(); qDebug() << reply->url(); qDebug() << reply->readAll(); //a.exec(); return 0; } 

There is a theoretical danger that the finished signal will come before QEventLoop starts and the code in that place will stop forever, then I would advise you to hang a timer on the quit before starting QEventLoop, for example:

 // Ждем 10 секунд QTimer::singleShot(10000, &loop, SLOT(quit()));