Problem with QNetworkAccessManager and Thread



  • Hello, i m beginner in Qt c++.
    I m trying to do an application when a click on button, i get a big json from web site
    when i push button, my thread start but i don't receive the response

    mainwindow.h

    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QtConcurrent>
    #include "mythread.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        MyThread *mThread;
    
    signals:
        void on_Stop();
    
    private slots:
        void on_pushButton_clicked();
    
    public slots:
        
    
    private:
        Ui::MainWindow *ui;
        MyThread mt;
    };
    
    #endif // MAINWINDOW_H
    

    mythread.h

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    
    #include <QThread>
    #include "qtconcurrentrun.h"
    
    #include <QtNetwork/QNetworkAccessManager>
    #include <QtNetwork/QNetworkRequest>
    #include <QtNetwork/QNetworkReply>
    
    class MyThread : public QObject
    {
        Q_OBJECT
    public:
        explicit MyThread(QObject *parent = 0);
        void start();
    
    
    signals:
        //void on_number(QString name, int number);
    
    public slots:
       
    
    private:
       bool mStop;
       QNetworkAccessManager * mgr;
    };
    
    #endif // MYTHREAD_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QFuture>
    #include <QtConcurrent/QtConcurrent>
    #include "mythread.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    
    }
    
    MainWindow::~MainWindow()
    {
        emit on_Stop();
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
    
    
        QFuture<void> test = QtConcurrent::run(&this->mt, &MyThread::start);
    }
    

    mythread.cpp

    #include "mythread.h"
    #include <QtCore>
    #include <QDebug>
    #include <QFuture>
    
    #include "qtconcurrentrun.h"
    
    #include <QtNetwork/QNetworkAccessManager>
    #include <QtNetwork/QNetworkRequest>
    #include <QtNetwork/QNetworkReply>
    
    MyThread::MyThread(QObject *parent) : QObject(parent)
    {
        mStop = false;
    }
    
    void MyThread::start(
            )
    {
    
    
        QNetworkAccessManager * mgr = new QNetworkAccessManager();
        QNetworkRequest request(QUrl("http://mywebsite/init"));
        connect(mgr, &QNetworkAccessManager::finished, [=](QNetworkReply *reply) {
            qDebug() << "hello reply is comming";
    
            reply->deleteLater();
    
        });
        mgr->get(request);
    
    }
    

    I don't see in debugoger "hello....."

    Can you help me please


  • Moderators

    @iTof26
    you have a memory leak: QNetworkAccessManager * mgr = new QNetworkAccessManager();

    i don't know if that is causing your issue, but my idea is that the lambda connection gets deleted somewhere.
    Is this the code you are really tested or did you just strip out some stuff?

    I guess your thread is automatically destroyed by QtConcurrent once it's finished (what is right after you call mgr->get(request);

    You can try to make sure the thread stays alive as long as the network reply hasn't returned.



  • Hi,
    I would work with the signals of the QNetworkReply instance returned by the call to get(request). There you can also connect to finished but to possible error signals of the call to get(request), as well.
    -Michael.


  • Lifetime Qt Champion

    Hi,

    Out of curiosity, why starting a new thread for that task ? QNetworkAccessManager already works asynchronously.

    Besides what @raven-worx already wrote, you are also shadowing your QNetworkAccessManager class member.



  • Ok, thank you for your answers
    How can i do a gui application with one button.
    When i click on this button, i have to make a request on a web site to get a big json without my gui application freeze?

    Please help me?


  • Moderators

    @iTof26 You can find examples here: http://doc.qt.io/qt-5/qnetworkaccessmanager.html
    And take a look at Qt example applications.


  • Moderators

    @iTof26 said in Problem with QNetworkAccessManager and Thread:

    How can i do a gui application with one button.
    When i click on this button, i have to make a request on a web site to get a big json without my gui application freeze?

    as @SGaist said, QNAM is already asynchronous in the behind the scenes. So simply move your code from your start() method inside the slot connected to the button click.



  • Your multithreading is COMPLETELY wrong.

    Start is executed in the calling thread, and never actually starts the thread as you are reimplementing the original method.

    Your code should go in the run() protected method instead and should start an event loop (call exec())

    also what is this?! QFuture<void> test = QtConcurrent::run(&this->mt, &MyThread::start);

    Edit
    Ok, my bad, thanks @raven-worx , I thought MyThread was derived from QThread. The problem then is just that you have no event loop in start


  • Moderators

    @VRonin said in Problem with QNetworkAccessManager and Thread:

    also what is this?! QFuture<void> test = QtConcurrent::run(&this->mt, &MyThread::start);

    thats the code which makes sure that the "thread" class (simple QObject in his case) is executed on a thread taken from the threadpool.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.