QT 实现HTTP部分功能(网页浏览和网页下载)

HTTP协议


以下来自维基百科
超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议[1]。HTTP是万维网的数据通信的基础。
设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

在Qt网络编程简介中我们提到过Qt中使用QNetworkAccessManager类和QNetworkReply类来进行HTTP的编程。网络请求由QNetworkRequest类来表示,它也作为与请求有关的信息(例如,任何头信息和使用加密)的容器。

在创建请求对象时指定的URL决定了请求使用的协议,目前支持HTTP、FTP和本地文件URLs的上传和下载。QNetworkAccessManager类用来协调网络操作,每当一个请求创建后,该类用来调度它,并发射信号来报告进度。该类还协调cookies的使用,身份验证请求,及其代理的使用等。对于网络请求的应答使用QNetworkReply类表示,它会在请求被完成调度时由QNetworkAccessManager来创建。QNetworkReply提供的信号可以用来单独的监视每一个应答

QT 中实现网页浏览功能(QT4.8 或者5.8 都行)

  1. 新建一个gui 项目,如下图, 在por文件中加上QT += core gui network

  2. 在ui文件中放一个Text Browser部件
    在这里插入图片描述

  3. 然后.h 文件如下: QtNetwork 是网络总的头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void ReplyFinished(QNetworkReply*);

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager* m_manager{nullptr};
};

#endif // MAINWINDOW_H
  1. cpp文件如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_manager = new QNetworkAccessManager(this);
    /// 创建了一个QNetworkAccessManager类的实例,它用来发送网络请求和接收
    /// 应答。然后关联了管理器的finished()信号和我们自定义的槽,每当网络应答结束时都会发射这个信号。
    connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(ReplyFinished(QNetworkReply*)));
    //    connect(m_manager, &QNetworkAccessManager::finished(QNetworkReply*), this, [this]{
    //        ReplyFinished(QNetworkReply* reply);
    //    });
    /// 最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest类表示,get()函数返回一个QNetworkReply对象
    m_manager->get(QNetworkRequest(QUrl("http://www.shanghai.gov.cn/")));
}

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

void MainWindow::ReplyFinished(QNetworkReply *reply)
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QString all = codec->toUnicode(reply->readAll());
    ui->textBrowser->setText(all);
    reply->deleteLater();
}

  1. 这里先创建了一个QNetworkAccessManager类的实例,它用来发送网络请求接收应答。然后关联了管理器的finished()信号和我们自定义的槽,每当网络应答结束时都会发射这个信号。
    最后使用了get()函数来发送一个网络请求,网络请求使用QNetworkRequest类表示,get()函数返回一个QNetworkReply对象。除了get()函数,管理器还提供了发送HTTP 的POST请求的post()函数。
  2. QNetworkReply继承自QIODevice类,所以可以操作一般的I/O设备一样来操作该类。
  3. 这里使用了readAll()函数来读取所有的应答数据,为了正常显示中文,使用了QTextCodec类来转换编码。在完成数据的读取后,需要使用deleteLater()来删除replay对象。

下面是程序运行的结果,(上海政府的一个网页), 在上面没有加上ssl,所有访问https是有问题。
在这里插入图片描述


这里再将整个过程简答叙述一遍:上面实现了最简单的应用HTTP协议下载网页的功能。QNetworkAccessManager类用于发送网络请求和接受回复,具体来说,它是用QNetworkRequest类来管理请求,QNetworkReply类进行接收回复,并对数据进行处理。

在上面的代码中,我们使用了下面的代码来发送请求:

manager->get(QNetworkRequest(QUrl("http://www.shanghai.gov.cn/")));

它返回一个QNetworkReply对象,这个后面再讲。我们只需知道只要发送请求成功,它就会下载数据。而当数据下载完成后,m_manager会发出finished()信号,我们关联了该信号:

connect(m_manager, SIGNAL(finished(QNetworkReply*)),
this,SLOT(replyFinished(QNetworkReply*)));

也就是说,当下载数据结束时,就会执行replyFinished()函数。在这个函数中我们对接收的数据进行处理:

QTextCodec *codec = QTextCodec::codecForName("utf8");
QString all = codec->toUnicode(reply->readAll());
ui->textBrowser->setText(all);

这里,为了能显示下载的网页中的中文,我们使用了QTextCodec 类对象,应用utf8编码。使用reply->readAll()函数就可以将下载的所有数据读出。然后,我们在textBrowser中将数据显示出来。当reply对象已经完成了它的功能时,我们需要将它释放,就是最后一条代码:

reply->deleteLater();

QT 实现下载文件功能

介绍一下整个程序执行的流程:开始我们先让进度条隐藏。当我们在Line
Edit中输入下载地址,点击下载按钮后,我们应用输入的下载地址,获得文件名,在磁盘上新建一个文件,用于保存下载的数据,然后进行链接,并显示进度条。在下载过程中,我们将每次获得的数据都写入文件中,并更新进度条,在接收完文件后,我们重新隐藏进度条,并做一些清理工作。根据这个思路,我们开始代码的编写。

.h 文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    void startRequest(QUrl url); //请求链接

private slots:
    void on_pushButton_clicked();  //下载按钮的单击事件槽函数
    void httpFinished();  //完成下载后的处理
    void httpReadyRead();  //接收到数据时的处理
    void updateDataReadProgress(qint64, qint64); //更新进度条

private:
    Ui::MainWindow *ui;

    QNetworkReply *reply;
    QUrl url;   //存储网络地址
    QFile *file;  //文件指针

    QNetworkAccessManager* manager;
};

#endif // MAINWINDOW_H

.cpp 文件


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

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

    manager = new QNetworkAccessManager(this);
    ui->progressBar->hide();

    connect(ui->pushButton, SIGNAL(clicked), this, SLOT(on_pushButton_clicked()));
}

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

void MainWindow::startRequest(QUrl url)
{
    reply = manager->get(QNetworkRequest(url));
    connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));

    connect(reply, SIGNAL(downloadProgress(qint64, qint64)),
            this, SLOT(updateDataReadProgress(qint64, qint64)));

    connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}

void MainWindow::on_pushButton_clicked()
{
    url = ui->lineEdit->text();
    QFileInfo info(url.path());
    QString fileName(info.fileName());
    if (fileName.isEmpty()) fileName = "index.html";
    file = new QFile(fileName);
    if(!file->open(QIODevice::WriteOnly))
    {
     qDebug() << "file open error";
     delete file;
     file = 0;
     return;
    }
    startRequest(url);
    ui->progressBar->setValue(0);
    ui->progressBar->show();
}

void MainWindow::httpFinished()
{
    ui->progressBar->hide();
    file->flush();
    file->close();
    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
}

void MainWindow::httpReadyRead()
{
    if (file) file->write(reply->readAll());
}

void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}

httpReadyRead函数中,先判断是否创建了文件,如果是,则读取返回的所有数据,然后写入到文件。该文件是在后面的“下载”按钮单击信号槽中创建并打开的。
updateDataReadProgress 函数设置了一下进度条的最大值和当前值。

执行后的结果:
在这里插入图片描述
总结: 上面就是HTTP 的两个简单例子,后续会更新FTP,TCP ,敬请期待~

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值