Займемся решением одной из самых простых, но и достаточно распространенных задач сетевого программирования: получения данных через GET-запрос. Для этого воспользуемся классом QNetworkAccessManager
.
Замечание: Не забудьте, что для использования сетевых библиотек в Qt необходимо явно затребовать их в pro
-файле проекта:
QT += network
Создадим простое приложение, которое загружает данные по URL, и отображает их в текстовом поле:
Замечание 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-запросов
Anonymous
Вы вообще демо видели? Всё жудко лагает и крашится, даже при стабильном интернете (я понимаю, что программа идет в один поток, но всё же)