Qt 网络编程之HTTP通信(QNetworkRequest、QNetworkReply、NetworkAccessManager)

一、高层网络协议类简介

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)表示文件下载进度

image.png

第二步:

  • 构造函数

//只列出了自己手写的代码,系统的默认代码省略了
#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);
    }
}

演示效果

image.png



————————————————

版权声明:本文为CSDN博主「江南、董少」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_41453285/article/details/100143875



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864