网络编程——网络下载
代码
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;
}
}
效果
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈