2
votes

I'm running Qt 4.8.1

I'm trying to use QNetworkRequest to send a request and I'm getting a 'QEventLoop: Cannot be used without QApplication' error. I believe I'm running within an event loop.

void WebLoader::load()
{
    QNetworkRequest request;
    request.setUrl(QUrl("http://www.bbc.co.uk/"));

    QNetworkAccessManager *manager = new QNetworkAccessManager();
    connect(manager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    QNetworkReply *reply = manager->get(request);
    connect(reply, SIGNAL(readyRead()), this, SLOT(checkForUpdateSlot()));
}

The manager->get(reply) call never returns.

This function is being called when a menu item is clicked upon. There is QWidget::event(QEvent) in its stack trace. The application is definitely running with the rest of a complex UI working.

as variations I've tried:

  1. using new QNetworkAccessManager(mainWindow) - mainWindow inherits from QMainWindow
  2. using new QNetworkAccessManager(application) - application inherits from QApplication
  3. calling load() from a customEvent
  4. calling load() from a timer callback

[edit]

I'm now constructing the QNetworkAccessManager in the MainWindow constructor:

MainWindow::MainWindow() : queryAnalyser(NULL)
{
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(managerFinished(QNetworkReply*)));

managerFinished is not being called.

I'm getting the debug IO: 'QObject: Cannot create children for a parent that is in a different thread. (Parent is MainWindow(0x28fcd0), parent's thread is QThread(0x4862828), current thread is QThread(0x7d90b70)'

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    WXApplication *a = WXApplication::getApp();

    MainWindow mainWin;

    mainWin.show();
    mainWin.checkArgs();
    return app.exec();
}
1
manager->get(reply) should be called after QNetworkAccessManager::finished(QNetworkReply*) signalBlood
I've now put the construction of the QNetworkAccessManager in the MainWindow Constructor: 'MainWindow::MainWindow() : queryAnalyser(NULL) { manager = new QNetworkAccessManager(this); connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(managerFinished(QNetworkReply*)));'user1827514

1 Answers

0
votes

Ensure that your QNetworkAccessManager is not destroyed at the end of the method which sens the request. If it is destroyed, your request is lost since the destroyed QNetworkAccessManager will not be able to send the finished() signal to the connected slot.

This is exactly what happened in the WebLoader::load(); method. The manager variable only exists during the method execution and the method will end before you will receive the reply.

What you can do is putting the QNetworkAccessManager in a global variable and use this global variable every time you need it :

Afile.hpp :

//...

#include <QNetworkAccessManager>
extern QNetworkAccessManager QNAM;

//...

Afile.cpp :

//...

#include "afile.hpp"
QNetworkAccessManager QNAM = QNetworkAccessManager();

//...

In your code (WebLoader::load(); for example) :

//...
#include "afile.hpp"
//...
QNetworkAccessManager * manager = &QNAM;
//...

In requests, set an originating object to "tag" requests and to ensure that the right methods will treat the right replies :

void WebLoader::load()
{
    QNetworkRequest request;
    request.setUrl(QUrl("http://www.bbc.co.uk/"));
    request.setOriginatingObject(this);

    QNetworkAccessManager * manager = &QNAM;
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    manager->get(request);
}

void WebLoader::checkForUpdateFinished(QNetworkReply* reply)
{
    if (reply == 0 || reply->request().originatingObject() != this)
    {
        return;
    }

    disconnect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    // Reply treatment

    reply->deleteLater();

    // ...
}

In your MainWindow constructor, forget the this if it is not necessary or use the QNAM global variable.