HTTP即超文本传输协议,它是一种文件传输协议。这一节中我们将讲解如何利用HTTP从网站上下载文件。

上一节中我们已经提到过了,现在Qt中使用QNetworkAccessManager类和QNetworkReply类来进行HTTP的编程。下面我们先看一个简单的例子,然后再进行扩展。

(一)最简单的实现。

1.我们新建Qt4 Gui QApplication

工程名为“http”,然后选中QtNetwork模块,最后Base class选择QWidget 。注意:如果新建工程时没有添加QtNetwork模块,那么就要手动在工程文件.pro中添加代码 QT += network ,表明我们使用了网络模块。

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

3..在widget.h中我们添加代码。

添加头文件:#include <QtNetwork>

私有变量private中:QNetworkAccessManager *manager;

私有槽函数private slots 中:void replyFinished(QNetworkReply *);

4.在widget.cpp文件中添加代码。

在构造函数中添加如下代码:

manager = new QNetworkAccessManager(this);  //新建QNetworkAccessManager对象

connect(manager,SIGNAL(finished(QNetworkReply*)),  //关联信号和槽

this,SLOT(replyFinished(QNetworkReply*)));

manager->get(QNetworkRequest(QUrl(“http://www.yafeilinux.com”))); //发送请求

然后定义函数:

void Widget::replyFinished(QNetworkReply *reply)  //当回复结束后

{

QTextCodec *codec = QTextCodec::codecForName(“utf8″);

//使用utf8编码,这样才可以显示中文

QString all = codec->toUnicode(reply->readAll());

ui->textBrowser->setText(all);

reply->deleteLater();   //最后要释放reply对象

}

5.运行效果如下。

6.代码分析。

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

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

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

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

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

1.我们更改widget.ui文件如下图。

这里我们添加了一个Line Edit ,一个Label ,一个Progress Bar 和一个Push Button ,它们的熟悉保持默认即可。我们在Push Button上点击鼠标右键,选择Go to slot ,然后选择clicked() ,进入其单击事件槽函数,现在我们先不写代码。

在写代码之前,我们先介绍一下整个程序执行的流程:

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

根据这个思路,我们开始代码的编写。

2.我们在widget.h文件中添加代码,完成后其部分内容如下。

class Widget : public QWidget {

Q_OBJECT

public:

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_pushButton_clicked();  //下载按钮的单击事件槽函数

void httpFinished();  //完成下载后的处理

void httpReadyRead();  //接收到数据时的处理

void updateDataReadProgress(qint64,qint64); //更新进度条

};

3.widget.cpp文件中的相关内容如下。

(1)构造函数中:

manager = new QNetworkAccessManager(this);

ui->progressBar->hide();

我们在构造函数中先隐藏进度条。等开始下载时再显示它。

(2)下载按钮的单击事件槽函数。

void Widget::on_pushButton_clicked()  //下载按钮

{

url = ui->lineEdit->text();

//获取在界面中输入的url地址,如http://zz.onlinedown.net/down/laolafangkuaijin.rar

QFileInfo info(url.path());

QString fileName(info.fileName());

//获取文件名

if (fileName.isEmpty()) fileName = “index.html”;

//如果文件名为空,则使用“index.html”,

//例如使用“http://www.yafeilinux.com”时,文件名就为空

file = new QFile(fileName);

if(!file->open(QIODevice::WriteOnly))

{   //如果打开文件失败,则删除file,并使file指针为0,然后返回

qDebug() << “file open error”;

delete file;

file = 0;

return;

}

startRequest(url);  //进行链接请求

ui->progressBar->setValue(0);  //进度条的值设为0

ui->progressBar->show();  //显示进度条

}

这里我们先从界面中获取输入的地址,然后分解出文件名。因为地址中可能没有文件名,这时我们就使用一个默认的文件名。然后我们用这个文件名新建一个文件,这个文件会保存到工程文件夹的debug文件夹下。下面我们打开文件,然后进行链接,并显示进度条。

(3)链接请求函数。

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)));

//更新进度条

}

在上一个例子中我们就提到了manager->get(QNetworkRequest(url)),返回的是一个QNetworkReply对象,这里我们获得这个对象,使用它完成显示数据下载进度的功能。这里主要是关联了几个信号和槽。当有可用数据时,reply就会发出readyRead()信号,我们这时就可以将可用的数据保存下来。就是在这里,实现了数据分段下载保存,这样比下载完所有数据再保存,要节省很多内存。而利用reply的downloadProgress()信号,很容易就实现了进度条的显示 。

(4)保存数据函数。

void Widget::httpReadyRead()   //有可用数据

{

if (file) file->write(reply->readAll());  //如果文件存在,则写入文件

}

这里当file可用时,将下载的数据写入文件。

(5)更新进度条函数。

void Widget::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)

{

ui->progressBar->setMaximum(totalBytes); //最大值

ui->progressBar->setValue(bytesRead);  //当前值

}

每当有数据到来时,都更新进度条。

(6)完成下载。

void Widget::httpFinished()  //完成下载

{

ui->progressBar->hide();

file->flush();

file->close();

reply->deleteLater();

reply = 0;

delete file;

file = 0;

}

这里只是当下载完成后,进行一些处理。

4.我们运行程序,效果如下。

下载网页文件:

下载华军软件园上的劳拉方块游戏:

下载完成后可以看到工程文件夹中debug文件夹中的下载的文件。

我们HTTP应用的内容就讲到这里,可以看到它是很容易的,也不需要你了解太多的HTTP的原理知识。关于相关的类的其他使用,你可以查看其帮助。在上面的例子中,我们只是为了讲解知识,所以程序还很不完善,对于一个真正的工程,我们还需要注意更多的细节,你可以查看Qt演示程序HTTP Client的源代码。

下一节我们将讲述FTP的内容。

转载于:https://www.cnblogs.com/weiqubo/archive/2010/08/03/1929980.html

Qt网络(二)HTTP编程相关推荐

  1. [Qt教程] 第31篇 网络(一)Qt网络编程简介

    [Qt教程] 第31篇 网络(一)Qt网络编程简介 楼主  发表于 2013-8-28 17:04:17 | 查看: 515| 回复: 0 Qt网络编程简介 版权声明 该文章原创于作者yafeilin ...

  2. Qt网络编程电子白板

    Qt网络编程电子白板 2018-08-11 08:44:04 天行健_地势坤 阅读数 915更多 分类专栏: Qt 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...

  3. 第十四章:Qt网络编程

    回顾: 第一章:Qt的概述 第二章:在Ubuntu编写第一个Qt程序 第三章:Qt的字符串和字符编码 第四章:Qt的信号和槽 第五章:Qt容器窗口(父窗口) 第六章:面向对象的Qt编程 第七章:Qt设 ...

  4. Qt网络编程概述(一)

    分享主题 Qt网络编程概述(一) Qt网络编程之QTCPSocket和QTCPServer实例(二) Qt网络编程之QUdpSocket实例(三) Qt网络编程概述 QtNetWork模块提供了若干类 ...

  5. Qt网络编程post请求,数据格式为json或x-www-form-urlencoded

    目录 Qt网络编程post请求,数据格式为json或x-www-form-urlencoded 一..H文件 1..h头文件 2..h主代码 二..CPP文件 1.主代码 三.响应信息 返回结果(Jo ...

  6. 【Qt入门第31篇】 网络(一)Qt网络编程简介

    导语 从这一节开始我们讲述Qt网络应用方面的编程知识.在开始这部分知识的学习之前,大家最好已经拥有了一定的网络知识和Qt的编程基础.在后面的教程中我们不会对一个常用的网络名词进行详细的解释,对于不太了 ...

  7. Qt网络编程之实例一GET方式

    看了两天的Qt网络编程,其实主要就是看了看QNetworkAccessManager.QNetworkRequest和QNetworkReply这三个类的主要内容.在之前,Qt网络编程主要是使用QHt ...

  8. qt android 网络编程实例,QT网络编程Tcp下C/S架构的即时通信实例

    先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include #include #include # ...

  9. Qt网络编程——TCP

    Qt网络编程--TCP 1. 概念 2. 服务器 3. 客户端 4. TCP服务器和客户端互传文件 5. 资源下载 1. 概念 TCP(Transmission Control Protocol, 传 ...

  10. Qt网络编程实战之HTTP服务器-安晓辉-专题视频课程

    Qt网络编程实战之HTTP服务器-30196人已学习 课程介绍         设计了一个实用的HTTP服务器,基于Qt的网络框架实现.先详细介绍Qt的网络.IO.线程..自定义事件.配置文件等类库的 ...

最新文章

  1. java中注解的使用与实例 (二)
  2. sass部分知识小结
  3. flask取mysql数据很慢_[flask 优化] 由flask-bootstrap,flask-moment引起的访问速度慢的原因及解决办法...
  4. ASP.NET教程11
  5. 腾讯汤道生:AI是产业互联网的“中央处理器”,数字技术融合打造产业新动能
  6. 【Spring】Spring Bean 生命周期
  7. 腾讯云的云数据库MYSQL配置
  8. python中ab+c*2_day2总结-Python中的基本语法
  9. tcp协议可以提供什么服务器,什么是TCP协议?
  10. 最全的Windows进程详解!
  11. 1、Linux软件源配置操作
  12. python语言实验——某年某月的天数 OJ1160
  13. php随机名人名言,php随机输出名人名言 实现代码
  14. leetcode 860.柠檬水找零 Java
  15. 生活中错误的英文——写错的标语
  16. 游戏开发19课 tilemap 创建瓦片
  17. 《管理学》第一章 管理与管理学
  18. 商界男士西服着装技巧
  19. java数组下标异常越界程序,Java程序运行时会自动检查数组的下标是否越界,如果越界,会抛出下面的哪一个异常?...
  20. WorldFirst能用于PayPal提现吗?怎么操作?

热门文章

  1. java blowfish ecb,node.js – 使用nodejs crypto和php的mcrypt解密blowfish-ecb
  2. 2020-2-6 蓝桥杯阶段模拟总结
  3. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_11-修改页面-前端-Api调用...
  4. 小D课堂 - 新版本微服务springcloud+Docker教程_2_02 微服务核心基础讲解
  5. springboot底层原理简述
  6. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_15maven工程servlet实例之导入项目依赖...
  7. ARP (地址解析协议)
  8. 【HDU 6299】Balanced Sequence
  9. AfxMessageBox详细使用说明
  10. windows 快捷方式(.lnk)代码执行漏洞(CVE-2017-8464 )[附EXP生成工具]