网络编程——网络下载

代码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QLabel>
#include <QPushButton>
#include <QProgressBar>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLineEdit>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    /* 网络管理 */
    QNetworkAccessManager *networkAccessManager;

    /* 标签 */
    QLabel *label[3];

    /* 按钮 */
    QPushButton *pushButton;
    /* 下载进度条 */
    QProgressBar *progressBar;

    /* 水平布局 */
    QHBoxLayout *hBoxLayout[2];

    /* 垂直布局 */
    QVBoxLayout *vBoxLayout;

    /* 水平容器 */
    QWidget *hWidget[2];

    /* 垂直容器 */
    QWidget *vWidget;

    /* 链接输入框 */
    QLineEdit *lineEdit;

private slots:
    /* 读取数据 */
    void readyReadData();

    /* 响应完成处理 */
    void replyFinished();

    /* 下载进度管理 */
    void imageDownloadProgress(qint64, qint64);

    /* 点击开始下载 */
    void startDownload();

    /* 响应错误处理函数 */
    void networkReplyError(QNetworkReply::NetworkError);
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QCoreApplication>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /* 设置主窗体的位置与大小 */
    this->setGeometry(0, 0, 800, 480);

    /* 标签 0, 显示下载的图像 */
    label[0] = new QLabel();
    /* 标签 1, 显示 URL 标签 */
    label[1] = new QLabel();
    /* 下载进度标签 */
    label[2] = new QLabel();

    /* 下载图片链接输入框 */
    lineEdit = new QLineEdit();

    /* 下载按钮 */
    pushButton = new QPushButton();

    /* 下载进度条 */
    progressBar = new QProgressBar();

    /* 水平布局 */
    hBoxLayout[0] = new QHBoxLayout();
    hBoxLayout[1] = new QHBoxLayout();

    /* 垂直布局 */
    vBoxLayout = new QVBoxLayout();

    /* 水平容器 */
    hWidget[0] = new QWidget();
    hWidget[1] = new QWidget();
    /* 垂直容器 */
    vWidget = new QWidget();

    label[1]->setText("URL 链接:");
    label[2]->setText("文件下载进度:");

    pushButton->setText("下载");

    /* 设置下载链接地址 */
    lineEdit->setText("https://ss0.bdstatic.com/70cFuH"
    "Sh_Q1YnxGkpoWK1HF6hhy/it/u=42710"
    "87328,1384669424&fm=11&gp=0.jpg");
    /* 设置标签的最小显示大小 */
    label[0]->setMinimumSize(this->width(),
                this->height() * 0.75);

    /* 根据文本文字大小自适应大小 */
    label[1]->setSizePolicy(QSizePolicy::Fixed,
                            QSizePolicy::Fixed);
    label[2]->setSizePolicy(QSizePolicy::Fixed,
                            QSizePolicy::Fixed);
    pushButton->setSizePolicy(QSizePolicy::Fixed,
                              QSizePolicy::Fixed);

    /* 水平布局 0 添加元素 */
    hBoxLayout[0]->addWidget(label[1]);
    hBoxLayout[0]->addWidget(lineEdit);
    hBoxLayout[0]->addWidget(pushButton);

    /* 设置水平布局 0 为水平容器的布局 0 */
    hWidget[0]->setLayout(hBoxLayout[0]);

    /* 水平布局 1 添加元素 */
    hBoxLayout[1]->addWidget(label[2]);
    hBoxLayout[1]->addWidget(progressBar);

    /* 设置水平布局 1 为水平容器的布局 1 */
    hWidget[1]->setLayout(hBoxLayout[1]);

    /* 垂直布局添加元素 */
    vBoxLayout->addWidget(label[0]);
    vBoxLayout->addWidget(hWidget[0]);
    vBoxLayout->addWidget(hWidget[1]);

    /* 设置垂直布局为垂直容器的布局 */
    vWidget->setLayout(vBoxLayout);

    /* 设置居中 */
    setCentralWidget(vWidget);

    /* 网络管理 */
    networkAccessManager = new QNetworkAccessManager(this);

    /* 信号槽连接 */
    connect(pushButton, SIGNAL(clicked()),
            this, SLOT(startDownload()));
}

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

void MainWindow::startDownload()
{
    /* 获取 URL 链接 */
    QUrl newUrl(QUrl(lineEdit->text()));

    /* 如果下载链接无效,则直接返回 */
    if (!newUrl.isValid()) {
        QMessageBox::information(this, "error", "invalid url");
        return;
    }

    /* 网络请求 */
    QNetworkRequest networkRequest;

    /* 设置下载的地址 */
    networkRequest.setUrl(newUrl);

    /* 网络响应 */
    QNetworkReply *newReply = networkAccessManager->get(networkRequest);

    /* 信号槽连接 */
    connect(newReply, SIGNAL(finished()),
            this, SLOT(replyFinished()));
    connect(newReply, SIGNAL(readyRead()),
            this, SLOT(readyReadData()));
    connect(newReply, SIGNAL(downloadProgress(qint64, qint64)),
            this, SLOT(imageDownloadProgress(qint64, qint64)));
    connect(newReply,
            SIGNAL(error(QNetworkReply::NetworkError)),
            this,
            SLOT(networkReplyError(QNetworkReply::NetworkError )));
}

void MainWindow::readyReadData()
{
    /* 设置按钮不可用,防止未完成,再次点击 */
    pushButton->setEnabled(false);

    /* 获取信号发送者 */
    QNetworkReply *reply = (QNetworkReply *)sender();

    QFile imageFile;
    /* 保存到当前路径,名称为"下载的.jpg" */
    imageFile.setFileName(QCoreApplication::applicationDirPath()
    + "/下载的.jpg");

    /* 如果此图片已经存在,则删除 */
    if (imageFile.exists())
        imageFile.remove();

    /* 读取数据 */
    QByteArray data = reply->readAll();
    /* 如果数据为空,返回 */
    if (data.isEmpty()) {
        qDebug()<<"data is null, please try it again!"<<endl;
        return;
    }

    /* 判断是不是 JPG 格式的图片,如果不是则返回 */
    if (! (data[0] == (char)0xff
        && data[1] == (char)0xd8
        && data[data.size() - 2] == (char)0xff
        && data[data.size() - 1] == (char)0xd9)) {
        qDebug()<<"not JPG data, please try it again!"<<endl;
        return;
    }

    /* 转为 QPixmap */
    QPixmap pixmap;
    pixmap.loadFromData(data);
    pixmap.save(imageFile.fileName());
}

void MainWindow::replyFinished()
{
    /* 获取信号发送者 */
    QNetworkReply *reply = (QNetworkReply *)sender();

    /* 防止内存泄漏 */
    reply->deleteLater();

    /* 判断当前执行程序下的图像是否下载完成 */
    QFile imageFile(QCoreApplication::applicationDirPath()
    + "/下载的.jpg");
    if (imageFile.exists()) {
        /* 显示下载的图像 */
        label[0]->setPixmap(QPixmap(imageFile.fileName()));
        qDebug() <<"已经成功下载,文件路径为:"
                 <<imageFile.fileName()<<endl;
    } else
        /* 清空显示 */
        label[0]->clear();

    /* 设置按钮可用 */
    pushButton->setEnabled(true);
}

void MainWindow::imageDownloadProgress(qint64 bytes, qint64 totalBytes)
{
    /* 设置进度条的最大值 */
    progressBar->setMaximum(totalBytes);
    /* 设置当前值 */
    progressBar->setValue(bytes);
}

/* 网络响应处理函数 */
void MainWindow::networkReplyError(QNetworkReply::NetworkError error)
    {
    switch (error) {
        case QNetworkReply::ConnectionRefusedError:
            qDebug()<<"远程服务器拒绝连接"<<endl;
            break;
        case QNetworkReply::HostNotFoundError:
            qDebug()<<"找不到远程主机名"<<endl;
            break;
        case QNetworkReply::TimeoutError:
            qDebug()<<"与远程服务器连接超时"<<endl;
            break;
        default:
            break;
    }
}

效果

imageimage

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值