原创

Qt的http下载的Demo

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://shazhenyu.blog.csdn.net/article/details/76230263

先看一下效果:



1、先建立需要引用的处理数据头文件toolfuction.h:

#ifndef TOOLFUCTION_H
#define TOOLFUCTION_H
#include <QString>
// 字节转KB、MB、GB
QString toolSize(qint64 bytes)
{
    QString strUnit;
    double dSize = bytes * 1.0;
    if (dSize <= 0)
    {
        dSize = 0.0;
    }
    else if (dSize < 1024)
    {
        strUnit = "Bytes";
    }
    else if (dSize < 1024 * 1024)
    {
        dSize /= 1024;
        strUnit = "KB";
    }
    else if (dSize < 1024 * 1024 * 1024)
    {
        dSize /= (1024 * 1024);
        strUnit = "MB";
    }
    else
    {
        dSize /= (1024 * 1024 * 1024);
        strUnit = "GB";
    }

    return QString("%1 %2").arg(QString::number(dSize, 'f', 2)).arg(strUnit);
}

// 速度转KB/S、MB/S、GB/S
QString speed(double speed)
{
    QString strUnit;
    if (speed <= 0)
    {
        speed = 0;
        strUnit = "Bytes/S";
    }
    else if (speed < 1024)
    {
        strUnit = "Bytes/S";
    }
    else if (speed < 1024 * 1024)
    {
        speed /= 1024;
        strUnit = "KB/S";
    }
    else if (speed < 1024 * 1024 * 1024)
    {
        speed /= (1024 * 1024);
        strUnit = "MB/S";
    }
    else
    {
        speed /= (1024 * 1024 * 1024);
        strUnit = "GB/S";
    }

    QString strSpeed = QString::number(speed, 'f', 2);
    return QString("%1 %2").arg(strSpeed).arg(strUnit);
}

// 秒转*d *h *m *s
QString timeFormat(int seconds)
{
    QString strValue;
    QString strSpacing(" ");
    if (seconds <= 0)
    {
        strValue = QString("%1s").arg(0);
    }
    else if (seconds < 60)
    {
        strValue = QString("%1s").arg(seconds);
    }
    else if (seconds < 60 * 60)
    {
        int nMinute = seconds / 60;
        int nSecond = seconds - nMinute * 60;

        strValue = QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }
    else if (seconds < 60 * 60 * 24)
    {
        int nHour = seconds / (60 * 60);
        int nMinute = (seconds - nHour * 60 * 60) / 60;
        int nSecond = seconds - nHour * 60 * 60 - nMinute * 60;

        strValue = QString("%1h").arg(nHour);

        if (nMinute > 0)
            strValue += strSpacing + QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }
    else
    {
        int nDay = seconds / (60 * 60 * 24);
        int nHour = (seconds - nDay * 60 * 60 * 24) / (60 * 60);
        int nMinute = (seconds - nDay * 60 * 60 * 24 - nHour * 60 * 60) / 60;
        int nSecond = seconds - nDay * 60 * 60 * 24 - nHour * 60 * 60 - nMinute * 60;

        strValue = QString("%1d").arg(nDay);

        if (nHour > 0)
            strValue += strSpacing + QString("%1h").arg(nHour);

        if (nMinute > 0)
            strValue += strSpacing + QString("%1m").arg(nMinute);

        if (nSecond > 0)
            strValue += strSpacing + QString("%1s").arg(nSecond);
    }

    return strValue;
}

#endif // TOOLFUCTION_H


2、建立网络下载类SDownloadNetwork

#ifndef SDOWNLOADNETWORK_H
#define SDOWNLOADNETWORK_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>

class SDownloadNetwork : public QNetworkAccessManager
{
    Q_OBJECT
public:
    explicit SDownloadNetwork(QObject *parent = 0);
    ~SDownloadNetwork();
    void execute(QString path);
private slots:
    void replyFinished(QNetworkReply *reply);
    void onAuthenticationRequest(QNetworkReply *reply, QAuthenticator *authenticator);
    void readyRead();
signals:
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);//下载过程
    void sigReplyFinished(int code,QString filePath);//获取响应的信息,状态码为200表示正常
private:
    QNetworkReply* m_pReply = Q_NULLPTR;
    QUrl m_url;
    QString m_strFileName;
    QString m_filePath;
};

#endif // SDOWNLOADNETWORK_H

#include "SDownloadNetwork.h"
#include <QDateTime>
#include <QFileInfo>

SDownloadNetwork::SDownloadNetwork(QObject *parent) : QNetworkAccessManager(parent)
{
    // 获取当前的时间戳,设置下载的临时文件名称
    QDateTime dateTime = QDateTime::currentDateTime();
    QString date = dateTime.toString("yyyy-MM-dd-hh-mm-ss-zzz");
    m_strFileName = QString("E:/%0.tmp").arg(date);

    connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
}

SDownloadNetwork::~SDownloadNetwork()
{
    // 终止下载
    if (m_pReply != NULL)
    {
        m_pReply->abort();
        m_pReply->deleteLater();
    }
}

// 设置URL及消息头,开始请求
void SDownloadNetwork::execute(QString path)
{
    m_url = QUrl(path);

    QNetworkRequest request;
    request.setUrl(m_url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/zip");

    connect(this, SIGNAL(authenticationRequired(QNetworkReply *, QAuthenticator *)),
            this, SLOT(onAuthenticationRequest(QNetworkReply *, QAuthenticator *)));

    m_pReply = get(request);
    connect(m_pReply, SIGNAL(downloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64)));
    connect(m_pReply, SIGNAL(readyRead()), this, SLOT(readyRead()));
}

#include <QDir>
void SDownloadNetwork::replyFinished(QNetworkReply *reply)
{
    // 获取响应的信息,状态码为200表示正常
    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    // 无错误返回
    if (reply->error() == QNetworkReply::NoError)  {
        // 重命名临时文件
        QFileInfo fileInfo(m_strFileName);
        QFileInfo newFileInfo = fileInfo.absolutePath() + m_url.fileName();
        QDir dir;
        if (dir.exists(fileInfo.absolutePath()))
        {
            if (newFileInfo.exists())
                newFileInfo.dir().remove(newFileInfo.fileName());
            QFile::rename(m_strFileName, newFileInfo.absoluteFilePath());
        }
    } else  {
        QString strError = reply->errorString();
        qDebug() << "Error:" << strError;
    }

    emit sigReplyFinished(statusCode.toInt(), m_filePath);
}

// 用户认证
void SDownloadNetwork::onAuthenticationRequest(QNetworkReply *reply, QAuthenticator *authenticator)
{
#ifdef User
    QByteArray password;
    password.append("123456");
    password = QByteArray::fromBase64(password);
    QString strPassword(password);
    authenticator->setUser("wang");
    authenticator->setPassword(strPassword);
#endif
}

// 本地写文件
void SDownloadNetwork::readyRead()
{
    QFileInfo fileInfo(m_strFileName);
    QFileInfo newFileInfo = fileInfo.absolutePath() + m_url.fileName();
    m_filePath = newFileInfo.absoluteFilePath();

    // 写文件-形式为追加
    QFile file(m_strFileName);
    if (file.open(QIODevice::Append)) {
        file.write(m_pReply->readAll());
    }
    file.close();
}

3、最后看下调用类MainWindow

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTime>
#include "sdownloadnetwork.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void onDownloadProcess(qint64 bytesReceived, qint64 bytesTotal);//下载过程
    void onReplyFinished(int code, QString path);//获取响应的信息,状态码为200表示正常
private:
    Ui::MainWindow *ui;
    QTime downloadTime;
    SDownloadNetwork*m_downloadNetwork = Q_NULLPTR;
    int m_nTime;
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "toolfuction.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_downloadNetwork = new SDownloadNetwork(this);
    connect(m_downloadNetwork, SIGNAL(downloadProgress(qint64, qint64)),
            this, SLOT(onDownloadProcess(qint64, qint64)), Qt::QueuedConnection);
    connect(m_downloadNetwork, SIGNAL(sigReplyFinished(int,QString)),
            this, SLOT(onReplyFinished(int,QString)), Qt::QueuedConnection);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    m_downloadNetwork->execute(ui->lineEdit->text());
    downloadTime.start();
    m_nTime = 0;
}

#include <qmath.h>
// 计算下载大小、速度、剩余时间
void MainWindow::onDownloadProcess(qint64 bytesReceived, qint64 bytesTotal)
{
    QString text;
    // 总时间
    int nTime = downloadTime.elapsed();//返回从上一次调用start所用的时间
    // 本次下载所用时间
    nTime -= m_nTime;

    // 下载速度
    double dBytesSpeed = (bytesReceived * 1000.0) / nTime;
    double dSpeed = dBytesSpeed;

    //剩余时间
    qint64 leftBytes = (bytesTotal - bytesReceived);
    double dLeftTime = (leftBytes * 1.0) / dBytesSpeed;

    text.append(" Speed:"+speed(dSpeed));
    text.append("\n Lave time:" + timeFormat(qCeil(dLeftTime)));
    text.append("\n File total Size:" + toolSize(bytesTotal));
    text.append("\n Download Size:" +toolSize(bytesReceived));

    ui->progressBar->setMaximum(bytesTotal);
    ui->progressBar->setValue(bytesReceived);
    ui->label_tip->setText(text);
    // 获取上一次的时间
    m_nTime = nTime;
}

#include <QMessageBox>
void MainWindow::onReplyFinished(int code, QString path)
{
    bool b = code == 200;
    QMessageBox::information(this,"DownLoad",b?"Success":"Fail");
    qDebug() << "Path:" << path;
}


文章最后发布于: 2017-07-28 10:45:06
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 代码科技 设计师: Amelia_0503

分享到微信朋友圈

×

扫一扫,手机浏览