IT Notes

QNetworkAccessManager: Простейшие GET-запросы

Займемся решением одной из самых простых, но и достаточно распространенных задач сетевого программирования: получения данных через GET-запрос. Для этого воспользуемся классом QNetworkAccessManager.

Замечание: Не забудьте, что для использования сетевых библиотек в Qt необходимо явно затребовать их в pro-файле проекта:

QT += network

Создадим простое приложение, которое загружает данные по URL, и отображает их в текстовом поле:

qnetworkaccessmanager-demo-thumbnail

Замечание 1: Компонент QTextEdit автоматически преобразовывает HTML-код в его читаемое представление, поэтому мы получаем очень ограниченную версию браузера (без работающих гиперссылок, css, изображений и JavaScript). Если же вам нужно полноценное отображение веб-страниц, то советую обратить внимание на QWebView.

Замечание 2: Наше приложение может загружать не только веб-страницы (и прочую текстовую информацию), но и бинарные данные (например, изображения) по их URL. Все упирается в визуализацию, которой сейчас нет.

И сразу к делу. Заголовочный файл networkmanagerdemowidget.h:

#ifndef NETWORKMANAGERDEMOWIDGET_H
#define NETWORKMANAGERDEMOWIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>

namespace Ui {
class NetworkManagerDemoWidget;
}

class NetworkManagerDemoWidget : public QWidget {
    Q_OBJECT

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

private slots:
    void onGo();
    void onFinished( QNetworkReply* reply );

private:
    Ui::NetworkManagerDemoWidget* ui;

    QNetworkAccessManager m_manager;

};

#endif // NETWORKMANAGERDEMOWIDGET_H

Реализация networkmanagerdemowidget.cpp:

#include "networkmanagerdemowidget.h"
#include "ui_networkmanagerdemowidget.h"

#include <QNetworkReply>

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

    connect( ui->bnGo, SIGNAL( clicked( bool ) ), SLOT( onGo() ) );

    connect( &m_manager, SIGNAL( finished( QNetworkReply* ) ), SLOT( onFinished( QNetworkReply* ) ) );
}

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

void NetworkManagerDemoWidget::onGo() {
    ui->lbStatus->setText( "Working…" );

    QString urlText = ui->edUrl->text().trimmed();
    m_manager.get( QNetworkRequest( QUrl( urlText ) ) );
}

void NetworkManagerDemoWidget::onFinished( QNetworkReply* reply ) {
    if( reply->error() == QNetworkReply::NoError ) {
        QString data = QString::fromUtf8( reply->readAll() );
        ui->textEdit->setText( data );

        ui->lbStatus->setText( "Ready!" );
    } else {
        ui->lbStatus->setText( reply->errorString() );
    }

    // Мы сами должны освободить память для reply
    // Однако делать это через delete нельзя
    reply->deleteLater();
}

Важно: Результат выполнения запроса приходит к нам асинхронно через сигнал finished() объекта m_manager. За освобождение ресурсов ответа reply ответственны мы, поэтому для предотвращения утечки памяти нужно вызвать reply->deleteLater().

Замечание: URL должен быть полным, поэтому без указания протокола (например http://) обработка запроса окончится неудачей.

Исходники

 Скачать пример использования QNetworkAccessManager для выполнения GET-запросов

Похожие публикации

Комментарии

Вы вообще демо видели? Всё жудко лагает и крашится, даже при стабильном интернете (я понимаю, что программа идет в один поток, но всё же)