一、高层网络协议类简介
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