Qt выполнить множественное получение с QNetworkAccessManager - PullRequest
0 голосов
/ 02 ноября 2018

Мне нужно выполнить много запросов на получение, и они должны обрабатываться разными способами. Пока у меня есть такой простой подход, который работает:

enter image description here

А вот код для .h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void finish(QNetworkReply *reply);

    void finish2(QNetworkReply *reply);

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager* manager;
};

#endif // MAINWINDOW_H

И код для .cpp:

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

#include <QDebug>

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

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

//First request here...
void MainWindow::on_pushButton_clicked()
{
    manager = new QNetworkAccessManager(this);
    connect(manager, &QNetworkAccessManager::finished, this, &MainWindow::finish);

    manager->get(QNetworkRequest{QUrl{"http://www.link.com/path/"}});
}

//... is completed here
void MainWindow::finish(QNetworkReply *reply) {
    if (reply->error()) {
        ui->lineEdit->setText("error");
        qDebug() << reply->errorString();
    } else {
            ui->lineEdit->setText(QString{reply->readAll()});
    }
}

//Second request here...
void MainWindow::on_pushButton_2_clicked()
{
    manager = new QNetworkAccessManager(this);
    connect(manager, &QNetworkAccessManager::finished, this, &MainWindow::finish2);

    manager->get(QNetworkRequest{QUrl{"https://ergast.com/api/f1/2008/5.json"}});
    qDebug() << "chiamata";
}

//... is completed here
void MainWindow::finish2(QNetworkReply *reply) {
    if (reply->error()) {
        ui->lineEdit_2->setText("error");
        qDebug() << reply->errorString();
    } else {
            ui->lineEdit_2->setText(QString{reply->readAll()});
    }
}

Когда я нажимаю обе кнопки, запросы происходят, но мой пользовательский интерфейс блокируется. Я попробовал этот подход, потому что я видел во многих примерах, что хорошо иметь QNetworkAccessManager* manager; как личное поле и использовать его повторно.

Не похоже, кстати, лучший подход. Есть ли правильный способ сделать несколько звонков?

Должен ли я объявить, может быть, массив QNetworkAccessManager* и выполнить там все вызовы?


Я также видел, что есть возможность создать личное поле с именем QNetworkReply* reply; и затем использовать его следующим образом:

manager = new QNetworkAccessManager(this);  
reply = manager->get(QNetworkRequest{QUrl{"http://www.link.com/path/"}});
connect(manager, &QNetworkReply::finished, this, &MainWindow::finish);

Я думаю, что это эквивалентно методу, который я использую, но в этом случае я не знаю, как обрабатывать несколько запросов, потому что я привязан к методу finish, и я должен реализовать всю логику там.

1 Ответ

0 голосов
/ 02 ноября 2018

Я проверил ваш код и не заметил, что графический интерфейс пользователя заблокирован, кроме того, что у вас не должно быть проблем с сигналами и слотами. Однако я вижу, что вы создаете динамическую память без необходимости, в следующем коде я подключаю QNetworkReply к слоту, фильтрую через QUrl и удаляю QNetworkReply:

*. Ч

...
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void onReplyfinished();

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager *manager;
...

*. Каст

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

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

void MainWindow::on_pushButton_clicked()
{
   QNetworkReply *reply = manager->get(QNetworkRequest{QUrl{"http://www.link.com/path/"}});
   connect(reply, &QNetworkReply::finished, this, &MainWindow::onReplyfinished);
}

void MainWindow::on_pushButton_2_clicked()
{
   QNetworkReply *reply = manager->get(QNetworkRequest{QUrl{"https://ergast.com/api/f1/2008/5.json"}});
   connect(reply, &QNetworkReply::finished, this, &MainWindow::onReplyfinished);
}

void MainWindow::onReplyfinished()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
    if(reply->url() == QUrl{"http://www.link.com/path/"}){
        ui->lineEdit->setText(reply->error() ? "error": reply->readAll());
    }
    else if (reply->url() == QUrl{"https://ergast.com/api/f1/2008/5.json"}){
        ui->lineEdit_2->setText(reply->error() ? "error": reply->readAll());
    }
    reply->deleteLater();
}
...