0

I want to use QNetWorkAccessManager to finish HTTP-GET and try to pass a value to the reply_finished slot,then I hope get feedback from the slot to its call function(e.g. MainWindow).I used https://stackoverflow.com/a/21362640/7519936 and pass a point as value to the reply_finished slot, but my application crashed.

Here are my MainWindow code:

QHash<QNetworkReply*, QString*> data_storage;
QString data="";
manager = new QNetworkAccessManager(this);
QNetworkReply* reply =manager->get(QNetworkRequest(QUrl("http://example.com")));
data_storage[reply] = &data;
connect(manager, SIGNAL(finished(QNetworkReply*)),this,SLOT(reply_Finished(QNetworkReply*)));

The reply_finshed slot code:

void MainWindow::reply_Finished(QNetworkReply *reply)
{
    data_storage.value(reply)->append("test");
    data_storage.remove(reply);
    //other 
}

Please do not mind my English. Please help me, thanks!

Community
  • 1
  • 1
  • What does `data_storage.remove(reply)` do -- does it `delete` the reply? And what does your debugger say the call stack is at the point of the crash? – G.M. Jul 02 '17 at 10:54
  • @G.M. I found a same question on stackoverflow,and i used its way with my plan,but my application crashed. – xiazhanjian Jul 02 '17 at 11:09
  • Where are you reading `response` from `reply`? You are trying to store a the reference of local variable (`data`) into the `QHash` which upon calling `reply_finished` is `remove`d from the hash. I'm not sure if that what you intended in the first place. You should be reading response on `finished` signal and then use it. – Azeem Jul 02 '17 at 15:53
  • @Azeem I mean when the network finished signal emit,I can pass a value to the slot and can get the value by handling and return from the slot.Could you understand me?I hope get your help.Thanks. – xiazhanjian Jul 02 '17 at 16:40
  • The problem i think the pointer. Make sure that your pointer is not null. Better to use QHash, because QString internally use implicit share – Apin Jul 03 '17 at 00:47
  • @Apin If i do not use pointer,I think i could not handle and get feedback data from the slot.Or Can you tell me another idea? – xiazhanjian Jul 03 '17 at 02:00

1 Answers1

2

Here's a complete working example. I've this window:

enter image description here

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QString>
#include <QHash>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_btnSendRequest_clicked();

private:
    Ui::MainWindow *ui;

    QNetworkAccessManager               _manager;
    QHash< QNetworkReply*, QString* >   _storage;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QNetworkRequest>
#include <QUrl>

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

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnSendRequest_clicked()
{
    QNetworkRequest request { QUrl{ "http://www.stroustrup.com/" } };
    QNetworkReply* reply = _manager.get( request );

    QString* data = new QString{ "Test Data! " };

    _storage[ reply ] = data;

    connect( &_manager, &QNetworkAccessManager::finished,
             [this]( QNetworkReply* reply )
    {
        if ( reply->error() )
        {
            qWarning() << "Error:" << reply->errorString();
            return;
        }

        QString* data = _storage[ reply ];
        if ( data )
        {
            const auto& appendedData = data->append( "Appended data!" );

            qDebug() << "Data:" << appendedData;
            qDebug() << "Response:" << reply->readAll();

            _storage.remove( reply );
            delete reply;
            delete data;
        }
    });
}

I've used a lambda for the slot on QNetworkAccessManager::finished signal. Hope you can figure that out.

On clicking the Send Request button, the output will be:

Data: "Test Data! Appended Data!"
Response: "... www.stroustrup.com Homepage Source ..."

Azeem
  • 11,148
  • 4
  • 27
  • 40
  • Thanks for your help,and i tried to use your way,i think i could not get feedback when the network is finished,it may pass a value(data) but may not return value(data) to it call function .Could you understand and help me?My English is not good and i may not tell you my problem clearly,please do not mind. – xiazhanjian Jul 03 '17 at 13:05
  • @xiazhanjian: Your `data` is a local variable. Create it on heap and then it'll be okay to use that your way. – Azeem Jul 03 '17 at 13:07
  • Thanks for your help! – xiazhanjian Jul 04 '17 at 02:48
  • @xiazhanjian: You are welcome! Have you resolved your issue? – Azeem Jul 04 '17 at 04:16
  • No,i find my application also crashed when i tried to pass the data and get feedback.And i still try again...If i still have same question,i think i will ask your help. – xiazhanjian Jul 04 '17 at 04:22
  • @xiazhanjian: Maybe, there are other issues in your code. I suggest that you update your code that you doubt is causing this crash. – Azeem Jul 04 '17 at 04:23
  • @xiazhanjian: I tried your exact scenario and found out that `data` pointer becomes `NULL` when multiple requests are sent. So, I've first tested it for a valid pointer and then used it. I've updated my code in the example. – Azeem Jul 04 '17 at 05:02