Search code examples
getqthreadqnetworkaccessmanager

QNetworkAccessManager get called in a QThread because cyclic


I need to call a web request cyclically, so, the easy way to do that is, of course, create a thread and call my request followed by a sleep.. The issue is that I wrote my code and it basically works. When I try to call the get inside a QThread, I don't receive any result, the event associated to the response is never invoked:

class RemoteControl : public QObject {
    Q_OBJECT
    QNetworkAccessManager* manager;

public:
    explicit RemoteControl(QObject* parent = 0); 
    ~RemoteControl() {}

public slots:
    void process() {
        std::cout << "start" << std::endl;

        while (true)    {
            execute();
            std::cout << "called" << std::endl;
            sleep(5);
        }
    }
    void execute() {
        QUrl url("my request for num of visitors that works..");
        QNetworkRequest req;
        req.setUrl(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded"));
        QNetworkReply* reply = manager->get(req);
    }
    void downloadFinished(QNetworkReply* reply) {
        std::cout << "finished called" << std::endl;
        QByteArray resp = reply->readAll();
        std::cout << resp.data() << std::endl;
    }

signals:
    void finished();

    private:
    WebRequest* WebReq_;
};


RemoteControl::RemoteControl(bool* enable, LoggerHandle* Log, QObject* parent) : QObject(parent)
{
    enable_ = enable;
    Log_    = Log;
    running_ = false;
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this,
       SLOT(downloadFinished(QNetworkReply*)));
}

int main() {
    //.... my code....

    QThread* t3 = new QThread;
    RemoteContr->moveToThread(t3);
    QObject::connect(t3, SIGNAL(started()), RemoteContr, SLOT(process()));
    t3->start();

    //.... my code....
}

So, what happens is that using this code I didn't get any errors, in the output I can see start and called but never finished called.. it seems that the event downloadFinished is never called.

Can you help me to understand why? Something wrong in my class RemoteControl?

Thanks Andrea


Solution

  • You don't need a thread for this. The QNetworkAccessManager is asynchronous, so the calls you're using do not block. Instead of a thread, just do something like this in your main function:

    QTimer * timer = new QTimer; 
    connect(timer, SIGNAL(timeout()), RemoteContr, SLOT(execute());
    timer->start(5000);  // = 5 seconds
    

    Then, execute is invoked every 5 seconds, which seems to be what you want.

    By the way, I think the reason you aren't getting results is that the while loop in process is blocking the thread. You can get rid of the process slot with this approach.