一、高层网络协议类简介
Qt网络模块提供了一些类实现OSI 7层网络模型中高层的网络协议,如HTTP、FTP、SNMP等,这些类主要是QNetworkRequest、QNetworkReply、NetworkAccessManager
QNetworkRequest:通过一个URL地址发起网络协议请求,也保存网络请求的信息,目前支持HTTP、FTP和局部文件URLs的下载或上传
NetworkAccessManager:用于协调网络操作。在QNetworkRequest发起一个网络请求后,NetworkAccessManager负责发送网络请求,创建网络响应
QNetworkReply:表示网络请求的相应。由NetworkAccessManager在发送一个网络请求后创建一个网络响应。QNetworkReply提供finished()、readyRead()、downloadProgress()可以监测网络响应的执行情况,执行相应的操作
QNetworkReply是QIODevice的子类,所以QNetworkReply支持流读写功能,也支持异步或同步工作
二、演示案例
第一步:
创建一个基于QMainWindow的项目,类名采取默认值。并设计界面
在URL中输入一个网络文件URL,设置下载文件保存路径后,点击下载按钮开始下载文件到目录中。进度条(Progress Bar)表示文件下载进度
第二步:
构造函数
//只列出了自己手写的代码,系统的默认代码省略了
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QDir>
#include <QMessageBox>
#include <QUrl>
#include <QFileInfo>
class MainWindow : public QMainWindow
{
private:
QNetworkAccessManager networkManager; //网络管理
QNetworkReply *reply; //网络响应
QFile *downloadedFile; //下载保存的临时文件
private slots:
//自定义槽函数
void on_finished();
void on_readyRead();
void on_downloadProgress(qint64 bytesRead,qint64 totalBytes);
};
第三步:
缺省路径按钮的响应函数
//在当前应用程序目录下创建一个名为temp的临时目录
void MainWindow::on_btnDefaultPath_clicked()
{
//获取当前应用程序的路径
QString curPath=QDir::currentPath();
//在当前目录下创建一个临时目录temp
QDir dir(curPath);//打开当前应用程序的路径
QString sub="temp";
dir.mkdir(sub);
ui->editPath->setText(curPath+"/"+sub+"/");
}
第四步:
下载按钮的响应函数
void MainWindow::on_btnDefaultPath_clicked()
{
//获取当前应用程序的路径
QString curPath=QDir::currentPath();
//在当前目录下创建一个临时目录temp
QDir dir(curPath);//打开当前应用程序的路径
QString sub="temp";
dir.mkdir(sub);
ui->editPath->setText(curPath+"/"+sub+"/");
}
void MainWindow::on_btnDownload_clicked()
{
//判断是否输入了URL
QString urlSpec=ui->editURL->text().trimmed();
if(urlSpec.isEmpty())
{
QMessageBox::information(this,QStringLiteral("错误"),QStringLiteral("请指定需要下载的文件URL"));
return;
}
//将路径转为一个URL变量,判断输入的URL是否有误
QUrl newUrl=QUrl::fromUserInput(urlSpec);
if(!newUrl.isValid())
{
QMessageBox::information(this,QStringLiteral("错误"),QString(QStringLiteral("无效URL:%1\n错误信息:%2")).arg(urlSpec,newUrl.errorString()));
return;
}
//判断是否打开了一个目录来保存下载的文件
QString tempDir=ui->editPath->text().trimmed();
if(tempDir.isEmpty())
{
QMessageBox::information(this,QStringLiteral("错误"),QStringLiteral("请指定下载文件保存目录"));
return;
}
//如果想要下载的文件已经存在了,则先移除原先存在的文件
QString fullFileName=tempDir+newUrl.fileName();
if(QFile::exists(fullFileName))
QFile::remove(fullFileName);
//尝试打开要下载的文件
downloadedFile=new QFile(fullFileName);
if(!downloadedFile->open(QIODevice::WriteOnly))
{
QMessageBox::information(this,QStringLiteral("错误"),QStringLiteral("临时文件打开错误"));
return;
}
ui->btnDownload->setEnabled(false);
//用QNetworkAccessManager发布网络请求,请求下载URL地址表示的文件并创建网络响应
reply=networkManager.get(QNetworkRequest(newUrl));
//关联信号与槽
connect(reply,SIGNAL(finished()),this,SLOT(on_finished()));
connect(reply,SIGNAL(readyRead()),this,SLOT(on_readyRead()));
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),
this,SLOT(on_downloadProgress(qint64,qint64)));
}
第五步:
3个自定义槽函数
void MainWindow::on_readyRead()
{
//读取下载的数据
downloadedFile->write(reply->readAll());
}
void MainWindow::on_downloadProgress(qint64 bytesRead,qint64 totalBytes)
{
//设置进度条的值
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(bytesRead);
}
//网络请求结束之后
void MainWindow::on_finished()
{
QFileInfo fileInfo;
fileInfo.setFile(downloadedFile->fileName());
//关闭打开的网络文件,然后置空
downloadedFile->close();
delete downloadedFile;
downloadedFile=Q_NULLPTR;
//删除网络响应并置空
reply->deleteLater();
reply=Q_NULLPTR;
QMessageBox::information(this,QStringLiteral("提示"),QStringLiteral("下载成功"));
//如果设置了下载完成后打开,就打开文件
if(ui->checkOpen->isChecked())
{
//调用缺省的应用程序软件打开下载的文件
QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
ui->btnDownload->setEnabled(true);
}
}
演示效果
————————————————
版权声明:本文为CSDN博主「江南、董少」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41453285/article/details/100143875

