本文章介绍如何利用HTTP从网站上下载文件。在Qt网络编程中,需要用到协议,即HTTP。它是超文本传输协议,它是一种文件传输协议。对于HTTP就不多解释了。

Qt网络编程中,需要用到协议,即HTTP。它是超文本传输协议,它是一种文件传输协议。这一节中我们将讲解如何利用HTTP从网站上下载文件。使用的编程环境为Windows下基于Qt4.6.3的Qt Creator 1.3.1

一、最简单的实现。

1.我们新建Qt 4 Gui QApplication 。

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

  1. QT += network

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

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

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

添加头文件:#include

私有变量private中:QNetworkAccessManager *manager;

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

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

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

  1. manager = new QNetworkAccessManager(this);  //新建QNetworkAccessManager对象
  2. connect(manager,SIGNAL(finished(QNetworkReply*)),  //关联信号和槽
  3. this,SLOT(replyFinished(QNetworkReply*)));
  4. manager->get(QNetworkRequest(QUrl(“http://www.yafeilinux.com”))); //发送请求

然后定义函数:

  1. void Widget::replyFinished(QNetworkReply *reply)  //当回复结束后
  2. {
  3. QTextCodec *codec = QTextCodec::codecForName(“utf8″);
  4. //使用utf8编码,这样才可以显示中文
  5. QString all = codec->toUnicode(reply->readAll());
  6. ui->textBrowser->setText(all);
  7. reply->deleteLater();   //最后要释放reply对象
  8. }

5.运行效果如下。

6.代码分析。

上面实现了最简单的应用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();
 
二、功能扩展

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

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


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

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

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

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

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


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

(1)构造函数中:


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

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


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

(3)链接请求函数。

  1. void Widget::startRequest(QUrl url)  //链接请求
  2. {
  3. reply = manager->get(QNetworkRequest(url));
  4. //下面关联信号和槽
  5. connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
  6. //下载完成后
  7. connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
  8. //有可用数据时
  9. connect(reply,SIGNAL(downloadProgress(qint64,qint64)),
  10. this,SLOT(updateDataReadProgress(qint64,qint64)));
  11. //更新进度条
  12. }

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

(4)保存数据函数。

  1. void Widget::httpReadyRead()   //有可用数据
  2. {
  3. if (file) file->write(reply->readAll());  //如果文件存在,则写入文件
  4. }

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

(5)更新进度条函数。

  1. void Widget::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
  2. {
  3. ui->progressBar->setMaximum(totalBytes); //最大值
  4. ui->progressBar->setValue(bytesRead);  //当前值
  5. }

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

(6)完成下载。

  1. void Widget::httpFinished()  //完成下载
  2. {
  3. ui->progressBar->hide();
  4. file->flush();
  5. file->close();
  6. reply->deleteLater();
  7. reply = 0;
  8. delete file;
  9. file = 0;
  10. }

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

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

下载网页文件:

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

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

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

http://blog.csdn.net/zhangbinsijifeng/article/details/47605123

qt http 下载文件的更多相关文章

  1. QT:多线程HTTP下载文件

    这里的线程是指下载的通道(和操作系统中的线程不一样),一个线程就是一个文件的下载通道,多线程也就是同时开起好几个下载通道.当服务器提供下载服务时,使用下载者是共享带宽的,在优先级相同的情况下,总服务器 ...

  2. QT实现,通过URL下载文件的接口实现

    今天来把坑填上. 具体就是提供一个URL,并通过这个URL下载文件. MyDownloader.h: #ifndef MYDOWNLOADER_H #define MYDOWNLOADER_H cla ...

  3. Asp.Net 下载文件的几种方式

    asp.net下载文件几种方式 protected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一个新的方法 ...

  4. Qt Creator下载和安装(详细教程)

    简介 Qt是跨平台的图形开发库,目前由Digia全资子公司 Qt Company 独立运营,官方网址: http://www.qt.io/ 也可以访问Qt项目域名:http://qt-project. ...

  5. 在IE中下载Office2007文件时在对话框中下载文件变成ZIP文件的问题

    导致原因: 从IIS或者Tomcat之类的Web服务器通过二进制流下载文件时(比如通过设置Header为Content-disposition:inline),如果被下载的文件是Office2007的 ...

  6. java客户端调用ftp上传下载文件

    1:java客户端上传,下载文件. package com.li.utils; import java.io.File; import java.io.FileInputStream; import ...

  7. .apk等常用文件下载出现如果应下载文件,请添加 iis MIME 映射。

    在下载.apk文件时出现错误. HTTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序.如果应下载文件,请添加 MIME 映射. ...

  8. QT入门学习笔记1:为什么要选QT及QT软件下载

    为什么选择QT? Qt突出的优势: ◆ Qt 是基于 C++ 的一种语言扩展(Extention) C/C++ 目前还是一种很多人都在学习的语言. Qt的好处就在于Qt本身可以被称作是一种 C++ 的 ...

  9. python+selenium下载文件——firefox

    修改Firefox的相关配置. 1.profile.set_preference('browser.download.folderList',2) 设置成0代表桌面,1代表下载到浏览器默认下载路径:2 ...

随机推荐

  1. Java---设计模式app小软件汇总应用

    写了一个app小软件,重点不在于软件,软件bug挺多,也没去修改. 这个小软件只是为了更好的说明和了解设计模块而做的. Java 程序设计–包结构 Java程序设计的系统体系结构很大一部分都体现在包结 ...

  2. java的CalssLoader

    类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1.0 就出现了,最初是为了满足 Ja ...

  3. 将汉字转为UTF-8编码

    01./** 02. * 将文件名中的汉字转为UTF8编码的串,以便下载时能正确显示另存的文件名. 03. * @param s 原文件名 04. * @return 重新编码后的文件名 05. */ ...

  4. ubuntu下,thinkphp验证码不能用

    首先安装gd库 使用apt-get方式为Ubuntu安装PHP+MYSQL+Apache 默认是没有GD库的 1.安装gd库 命令:sudo apt-get install php5-gd 2.给权限 ...

  5. Beanstalkd介绍

    特征 优先级:任务 (job) 可以有 0~2^32 个优先级, 0 代表最高优先级,beanstalkd 采用最大最小堆 (Min-max heap) 处理任务优先级排序, 任何时刻调用 reser ...

  6. .net 面试题(3)

    96.题目: 活期存款中,"储户"通过"存取款单"和"储蓄所"发生联系.假定储户包括:账号,姓名,电话,地址,存款额:"储蓄所&q ...

  7. C++编程规范之20:避免函数过长,避免嵌套过深

    摘要: 短胜于长,平胜于优,过长的函数和嵌套过深的代码块的出现,经常是因为没能赋予一个函数以一个紧凑的职责所致,这两种情况通常都能够通过更好的重构予以解决. 每个函数都应该顾其名而能知其义,易于理解的 ...

  8. INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES错误解决方法

    在安装APK文件时出现类似INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES的提示,同时类似的提示如下: Android Launch! adb is run ...

  9. Linux 与 BSD 有什么不同?

    Linux 与 BSD 有什么不同? 这篇文章是别人写的,并做了一点修改. 汉澳sinox就是基于bsd开发的,因此能够理解为一个bsd分支,可是由于sinox不开源,被排除在外.bsd不是商业软件, ...

  10. 实现Android 版网页快照功能

    现在一般的购物网站,在你完成交易后都会将页面拍照以免日后发生商务纠纷,而对于我们移动开发者这个传统互联网上的优秀经验也同样给了我们一些设计上的启迪,接下来我将几种实现思路写出来供大家参考. 方案一:使 ...