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. QT - C++ - HTTP Request and Reply
Forum Updated to NodeBB v4.3 + New Features

QT - C++ - HTTP Request and Reply

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 1.5k 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.
  • V Offline
    V Offline
    Vildnex
    wrote on last edited by
    #1

    I'm new to QT and I would like some help if could give it to me.

    So I'm trying to create a class which will look something like this

    class WeatherAPI : public QObject {
    Q_OBJECT
    public:
        explicit WeatherAPI(QObject *parent = nullptr);
    
    public slots:
        void readData(QNetworkReply *reply);
    
    private:
        QNetworkAccessManager *manager;
    };
    

    Where the constructor will be:

    WeatherAPI::WeatherAPI(QObject *parent) : QObject(parent) {
        manager = new QNetworkAccessManager(this);
        QObject::connect(manager, SIGNAL(finished(QNetworkReply * )), this, SLOT(readData(QNetworkReply * )));
        QUrl url("http://dummy.restapiexample.com/api/v1/employees");
        manager->get(QNetworkRequest(url));
    }
    

    and the readData function will be:

    void WeatherAPI::readData(QNetworkReply *reply) {
        if (reply->error() == QNetworkReply::NoError) {
            QStringList propertyNames;
            QStringList propertyKeys;
    
            QString strReply = (QString) reply->readAll();
    
            qDebug() << strReply;
    
            QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
    
            QJsonObject jsonObject = jsonResponse.object();
    
            QString data = jsonObject["status"].toString();
            qDebug() << data;
        } else {
            qDebug() << "ERROR";
        }
        delete reply;
    }
    

    And the call of the WeatherAPI will be done into mainwindow.cpp like this.

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
        ui->setupUi(this);
    
        WeatherAPI api(this);
    }
    

    Because I just care about that request to be done successfully for the moment at least.

    Now the tricky part comes, when I'm going to run this program it will never enter into readData
    function, I don't know why, so in other words, I'm NOT going to receive any reply.

    But, if I will change the constructor to be like this:

    WeatherAPI::WeatherAPI(QObject *parent) : QObject(parent) {
        QEventLoop eventLoop;
        QNetworkAccessManager manager;
        QObject::connect(&manager, SIGNAL(finished(QNetworkReply * )), &eventLoop, SLOT(quit()));
        QNetworkRequest req;
        QNetworkReply *reply;
        QString url = "http://dummy.restapiexample.com/api/v1/employees";
        req.setUrl(url);
        reply = manager.get(req);
        eventLoop.exec();
        QJsonDocument jsonPageDoc = QJsonDocument::fromJson(reply->readAll());
        QJsonObject jsonPageObj = jsonPageDoc.object();
        qDebug() << jsonPageObj["status"].toString();
    }
    

    Then everything is going to work properly, except that I can't do this because there is not going to be anything asynchrony, or in other words, everything is going to run on the main thread.
    Could any of you guys tell me what's wrong with my first approach and why is not working? Why my code is never going to execute the readData function?

    jsulmJ 1 Reply Last reply
    0
    • V Vildnex

      I'm new to QT and I would like some help if could give it to me.

      So I'm trying to create a class which will look something like this

      class WeatherAPI : public QObject {
      Q_OBJECT
      public:
          explicit WeatherAPI(QObject *parent = nullptr);
      
      public slots:
          void readData(QNetworkReply *reply);
      
      private:
          QNetworkAccessManager *manager;
      };
      

      Where the constructor will be:

      WeatherAPI::WeatherAPI(QObject *parent) : QObject(parent) {
          manager = new QNetworkAccessManager(this);
          QObject::connect(manager, SIGNAL(finished(QNetworkReply * )), this, SLOT(readData(QNetworkReply * )));
          QUrl url("http://dummy.restapiexample.com/api/v1/employees");
          manager->get(QNetworkRequest(url));
      }
      

      and the readData function will be:

      void WeatherAPI::readData(QNetworkReply *reply) {
          if (reply->error() == QNetworkReply::NoError) {
              QStringList propertyNames;
              QStringList propertyKeys;
      
              QString strReply = (QString) reply->readAll();
      
              qDebug() << strReply;
      
              QJsonDocument jsonResponse = QJsonDocument::fromJson(strReply.toUtf8());
      
              QJsonObject jsonObject = jsonResponse.object();
      
              QString data = jsonObject["status"].toString();
              qDebug() << data;
          } else {
              qDebug() << "ERROR";
          }
          delete reply;
      }
      

      And the call of the WeatherAPI will be done into mainwindow.cpp like this.

      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
          ui->setupUi(this);
      
          WeatherAPI api(this);
      }
      

      Because I just care about that request to be done successfully for the moment at least.

      Now the tricky part comes, when I'm going to run this program it will never enter into readData
      function, I don't know why, so in other words, I'm NOT going to receive any reply.

      But, if I will change the constructor to be like this:

      WeatherAPI::WeatherAPI(QObject *parent) : QObject(parent) {
          QEventLoop eventLoop;
          QNetworkAccessManager manager;
          QObject::connect(&manager, SIGNAL(finished(QNetworkReply * )), &eventLoop, SLOT(quit()));
          QNetworkRequest req;
          QNetworkReply *reply;
          QString url = "http://dummy.restapiexample.com/api/v1/employees";
          req.setUrl(url);
          reply = manager.get(req);
          eventLoop.exec();
          QJsonDocument jsonPageDoc = QJsonDocument::fromJson(reply->readAll());
          QJsonObject jsonPageObj = jsonPageDoc.object();
          qDebug() << jsonPageObj["status"].toString();
      }
      

      Then everything is going to work properly, except that I can't do this because there is not going to be anything asynchrony, or in other words, everything is going to run on the main thread.
      Could any of you guys tell me what's wrong with my first approach and why is not working? Why my code is never going to execute the readData function?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Vildnex said in QT - C++ - HTTP Request and Reply:

      WeatherAPI api(this);

      This is a local variable and will disappear as soon as constructor terminates.
      Either make it class member or allocate on the heap.

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

      1 Reply Last reply
      4
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        WeatherAPI api(this);

        This object no more exist once the contractor completes.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        2

        • Login

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