qt 之http学习

在Qt网络编程中,需要用到协议,即HTTP。它是超文本传输协议,它是一种文件传输协议。

新建工程名为“http”,然后选中QtNetwork模块,最后Base class选择QWidget。注意:如果新建工程时没有添加QtNetwork模块,那么就要手动在工程文件.pro中添加代码

  1. QT += network  

表明我们使用了网络模块。

2.我们在widget.ui文件中添加一个 Text Browser ,如下图。

Qt网络之HTTP编程

 

实现的代码如下:

widget.h文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <qtextcodec.h>
#include <QNetworkReply>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
    QNetworkAccessManager* manager;
private slots:
    void replyFinished(QNetworkReply *);
};

#endif // WIDGET_H

widget.cpp文件:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);
    connect(manager,SIGNAL(finished(QNetworkReply*)),  //关联信号和槽
                this,SLOT(replyFinished(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://www.baidu.com"))); //发送请求
}

Widget::~Widget()
{
    delete ui;
}
void Widget::replyFinished(QNetworkReply *reply)  //当回复结束后
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    //使用utf8编码,这样才可以显示中文
    QString all = codec->toUnicode(reply->readAll());
    ui->textBrowser->setText(all);
    reply->deleteLater();   //最后要释放reply对象
}

 

代码分析。

上面实现了最简单的应用HTTP协议下载网页的程序。QNetworkAccessManager类用于发送网络请求和接受回复,具体的,它是用QNetworkRequest类来管理请求,QNetworkReply类进行接收回复,并对数据进行处理。

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

  1. manager->get(QNetworkRequest(QUrl(“http://www.yafeilinux.com”))); 

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

  1. connect(manager,SIGNAL(finished(QNetworkReply*)),  
  2.             this,SLOT(replyFinished(QNetworkReply*))); 

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

  1. QTextCodec *codec = QTextCodec::codecForName(“utf8″); 
  2. QString all = codec->toUnicode(reply->readAll()); 
  3. ui->textBrowser->setText(all); 

这里,为了能显示下载的网页中的中文,我们使用了QTextCodec 类对象,应用utf8编码。

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

  1. reply->deleteLater(); 
 
二、功能扩展
开始我们先让进度条隐藏。当我们在Line 
Edit中输入下载地址,点击下载按钮后,我们应用输入的下载地址,获得文件名,在磁盘上新建一个文件,用于保存下载的数据,然后进行链接,并显示进度
条。在下载过程中,我们将每次获得的数据都写入文件中,并更新进度条,在接收完文件后,我们重新隐藏进度条,并做一些清理工作。

 


通过上面的例子可以看到,Qt中编写基于HTTP协议的程序是十分简单的,只有十几行代码。不过,一般我们下载文件都想要看到下载进度。下面我们就更改上面的程序,让它可以下载任意的文件,并且显示下载进度。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <qtextcodec.h>
#include <QNetworkReply>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void startRequest(QUrl url); //请求链接
protected:
    //void changeEvent(QEvent *e);

private:
    Ui::Widget *ui;
    QNetworkAccessManager* manager;
    QNetworkReply *reply;
    QUrl url; //存储网络地址
    QFile *file;//存储文件
private slots:
    void on_download_clicked();
    void httpFinshed();
    void httpReadyRead();
    void updataDataReadProcess(qint64,qint64 );//更新进度条
};

#endif // WIDGET_H

3.widget.cpp文件

#include "widget.h"
#include "ui_widget.h"

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

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

void Widget::on_download_clicked()
{
    url=ui->lineEdit->text();
    //获取在界面输入的url地址
    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 errror";
        delete file;
        file=0;
        return;
    }
    startRequest(url);//进行链接请求
    ui->progressBar->setValue(0);//进度条的值设为零
    ui->progressBar->show(); //显示进度条
}
void Widget::startRequest(QUrl url)  //链接请求
{
    reply = manager->get(QNetworkRequest(url));
    //下面关联信号和槽
    connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
    //下载完成后
    connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
    //有可用数据时
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),
            this,SLOT(updateDataReadProgress(qint64,qint64)));
    //更新进度条
}
void Widget::httpReadyRead()   //有可用数据
{
    if (file) file->write(reply->readAll());  //如果文件存在,则写入文件
}
void Widget::updataDataReadProcess(qint64 bytesRead, qint64 totalBytes)
 {
    ui->progressBar->setMaximum(totalBytes); //最大值
    ui->progressBar->setValue(bytesRead);  //当前值
}
void Widget::httpFinshed()  //完成下载
{
    ui->progressBar->hide();
    file->flush();
    file->close();
    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
}

我们HTTP应用的内容就讲到这里,可以看到它是很容易的,也不需要你了解太多的HTTP的原理知识。关于相关的类的其他使用,你可以查看其帮助









posted @ 2019-01-17 08:51  创造卓越人生  阅读(2815)  评论(0编辑  收藏  举报