Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QNetworkReply destroyed before completing

QNetworkReply destroyed before completing

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 319 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Laurentioos
    wrote on last edited by
    #1

    Hi guys,

    Quick disclaimer I've been at this for days and am probably overlooking something. I am also learning as I go so every chance I'm doing it very wrong. I've learned enough about QNetworkAccessManager etc to be dangerous but not competent :)

    The problem I have at the moment is that I need to run various get/post api calls to web services, which works fine if the code runs in a cli window but not a gui (QWidget) window. to narrow down the problem I created a test project with code snippets from tutorials:

    worker.h

    #ifndef WORKER_H
    #define WORKER_H
    
    #include <QObject>
    #include <QtDebug>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QNetworkRequest>
    #include <QAuthenticator>
    #include <QNetworkProxy>
    
    class worker : public QObject
    {
        Q_OBJECT
    public:
        explicit worker(QObject *parent = nullptr);
    
    signals:
    
    public slots:
        void get(QString location);
        void post(QString location, QByteArray data);
    private slots:
            void readyRead();
            void authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
            void encrypted(QNetworkReply *reply);
            void finished(QNetworkReply *reply);
            void networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible);
            void preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator);
            void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
            void sslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
    
    private:
    
            QNetworkAccessManager manager;
    
    };
    
    #endif // WORKER_H
    
    
    

    worker.cpp

    #include "worker.h"
    
    worker::worker(QObject *parent) : QObject(parent)
    {
        connect(&manager,&QNetworkAccessManager::authenticationRequired,this,&worker::authenticationRequired);
        connect(&manager,&QNetworkAccessManager::encrypted,this,&worker::encrypted);
        connect(&manager,&QNetworkAccessManager::networkAccessibleChanged,this,&worker::networkAccessibleChanged);
        connect(&manager,&QNetworkAccessManager::preSharedKeyAuthenticationRequired,this,&worker::preSharedKeyAuthenticationRequired);
        connect(&manager,&QNetworkAccessManager::proxyAuthenticationRequired,this,&worker::proxyAuthenticationRequired);
        connect(&manager,&QNetworkAccessManager::sslErrors,this,&worker::sslErrors);
    }
    
    void worker::get(QString location)
    {
        qInfo() << "getting from server...";
        QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(location)));
        connect(reply,&QNetworkReply::readyRead,this,&worker::readyRead);
    }
    
    void worker::post(QString location, QByteArray data)
    {
        qInfo() << "posting to server...";
        QNetworkRequest request = QNetworkRequest (QUrl(location));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"text/plain");
        QNetworkReply* reply = manager.post(request,data);
        connect(reply,&QNetworkReply::readyRead,this,&worker::readyRead);
    }
    
    void worker::readyRead()
    {
        qInfo() << "ReadyRead";
        QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
        if(reply) qInfo () <<reply->readAll();
    }
    
    void worker::authenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
    {
        Q_UNUSED(reply)
        Q_UNUSED(authenticator)
        qInfo() << "authenticationRequired";
    }
    
    void worker::encrypted(QNetworkReply *reply)
    {
        Q_UNUSED(reply)
        qInfo() << "encrypted";
    }
    
    void worker::finished(QNetworkReply *reply)
    {
        Q_UNUSED(reply)
        qInfo() << "finished";
    }
    
    void worker::networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility accessible)
    {
        Q_UNUSED(accessible)
        qInfo() << "networkAccessibleChanged";
    }
    
    void worker::preSharedKeyAuthenticationRequired(QNetworkReply *reply, QSslPreSharedKeyAuthenticator *authenticator)
    {
        Q_UNUSED(reply)
        Q_UNUSED(authenticator)
        qInfo() << "preSharedKeyAuthenticationRequired";
    }
    
    void worker::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
    {
        Q_UNUSED(proxy)
        Q_UNUSED(authenticator)
        qInfo() << "proxyAuthenticationRequired";
    }
    
    void worker::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
    {
        Q_UNUSED(reply)
        Q_UNUSED(errors)
        qInfo() << "sslErrors";
    }
    
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "worker.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        worker Worker;
        QByteArray data;
        data.append("param1=hello");
        data.append("&");
        data.append("param2=world");
        Worker.post("https://postman-echo.com/post",data);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    now I know the reply is being destroyed by adding the folowing code at the end of the post function

        connect(reply, &QObject::destroyed,
                [] { qDebug() << "Sender got deleted!"; });
    

    for context the reason I'm attempting to call the functions within the mainwindow, is that there will be push buttons connected to functions that will download file, get a specific page etc.

    Thanks in advance!

    1 Reply Last reply
    0
    • eyllanescE Offline
      eyllanescE Offline
      eyllanesc
      wrote on last edited by eyllanesc
      #2

      @Laurentioos move worker Worker; to

      // ...
      private:
          Ui::MainWindow *ui;
          worker Worker;
      };
      

      read about od scope in variables

      If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

      1 Reply Last reply
      2
      • L Offline
        L Offline
        Laurentioos
        wrote on last edited by
        #3

        @eyllanesc I dont understand why I would move the variable to mainwindow.h?

        quick bit of reading though and I guess I misunderstood the parent child relationship. I had thought that Worker would be a child of MainWindow, and exist so long as MainWindow exists, where am I right to understand it will only exist within the context of the function because I'm storing the class in a variable?

        eyllanescE 1 Reply Last reply
        0
        • L Laurentioos

          @eyllanesc I dont understand why I would move the variable to mainwindow.h?

          quick bit of reading though and I guess I misunderstood the parent child relationship. I had thought that Worker would be a child of MainWindow, and exist so long as MainWindow exists, where am I right to understand it will only exist within the context of the function because I'm storing the class in a variable?

          eyllanescE Offline
          eyllanescE Offline
          eyllanesc
          wrote on last edited by eyllanesc
          #4

          @Laurentioos mmm, what you say about the relationship between QObjects is correct but creating a QObject inside a function that belongs to a class does not make the QObject a child of the class. In your case "Worker" is a local variable that will be destroyed as soon as the MainWindow constructor finishes executing. Please read https://doc.qt.io/qt-5/qobject.html#details.

          If you want it to be child then you must use a pointer and pass to this: worker *Worker = new worker(this);

          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

          1 Reply Last reply
          3
          • L Offline
            L Offline
            Laurentioos
            wrote on last edited by
            #5

            Thanks @eyllanesc while I've not yet got this working in my main app I now understand why it wasn't. I think for the small size of this app I'll likely just declare the Worker variable outside the scope of any function within mainwindow.cpp

            I think I may also have some reading to do to properly understand your last suggestion re pointer and it's use case.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi

              @Laurentioos said in QNetworkReply destroyed before completing:

              I think for the small size of this app I'll likely just declare the Worker variable outside the scope of any function within mainwindow.cpp

              The size of the app does not matter to do things correctly ;-)

              If anything, make it a member variable of your class as the first suggestion of @eyllanesc. Sprinkling your code with global variables is a bad idea in any case.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • L Offline
                L Offline
                Laurentioos
                wrote on last edited by
                #7

                @SGaist I know you're right haha

                I was struggling to understand the first suggestion still though, am I right to understand including the worker.h and declaring "worker Worker;" within the MainWindow.h is the correct way to go?

                jsulmJ 1 Reply Last reply
                0
                • L Laurentioos

                  @SGaist I know you're right haha

                  I was struggling to understand the first suggestion still though, am I right to understand including the worker.h and declaring "worker Worker;" within the MainWindow.h is the correct way to go?

                  jsulmJ Online
                  jsulmJ Online
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Laurentioos said in QNetworkReply destroyed before completing:

                  am I right to understand including the worker.h and declaring "worker Worker;" within the MainWindow.h is the correct way to go?

                  yes. To be more precise: inside the MainWindow class:

                  class MainWindow : ...
                  {
                  private:
                        worker Worker;
                  

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved