Qt系列文章021-HTTP文件上传

1 前言

    在前面写完HTTP相关下载后,上传肯定也是少不了的,虽然平时我们上传用的少,但是也是一个不可或缺的功能,所以今天打算简单的讲讲Qt相关的Http上传功能。

公众号:Qt实战,各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发。

公众号:Qt入门和进阶,专门介绍Qt/C++相关知识点学习,帮助Qt开发者更好的深入学习Qt。多位Qt元婴期大神,一步步带你从入门到进阶,走上财务自由之路。

官方店:https://shop114595942.taobao.com//

2 上传接口

    有了前面的关于Qt网络的基础类的了解,下面的介绍大家肯定会一点就通!当然我们的上传同样是基于 QNetworkAccessManager 开发的, 大家可以回忆下在前面下载的章节中我们用到的是Get,如下:

QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)

    是不是很有印象,所以上传也就是对应的post,Qt提供的get只有一个方法,而post有多个重载方法,说明上传的方法有多种,看你自己需要哪一种,如下:

QNetworkReply *post(const QNetworkRequest &request, QIODevice *data)
QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data)
QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart)

    每一个都是第二个参数不一样的,所以用到的方式也不一样,一般我们能用到的也就是第二个和第三个了,3是我比较推荐的使用方式,也是这次重点的介绍对象,也就是使用QHttpMultiPart 上传文件

3 程序介绍

    基于QByteArray的上传, 我们先使用第二个方法来上传文件,服务端这边是我这边用python搭建的一个简单的本地测试服务器,所以大家注意客户端就行!

    实例名称为HttpUpload, 下图是程序运行上传文件时的界面:
在这里插入图片描述
    在URL地址编辑框里输入一个上传的网络URL地址,我这边是默认的本地地址,所以直接127.0.0.1即可,点击选择上传的文件按钮在弹出的选择文件框中选择需要上传的文件,设置上传文件的路径后,单击上传按钮就可以开始上传文件到对应的服务端的目录下。进度条可以显示文件上传进度。

   实例HttpUpload主界面是基于QWidget的窗口类HttpUpload,使用UI设计器设计界
面,HttpUpload 类的定义如下:

class HttpUpload : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_pushButton_selectUploadFile_clicked();
    void on_pushButton_startUpload_clicked();

    //自定义槽信号
    void onUpLoadFinished();
    void onUpLoadError(QNetworkReply::NetworkError errorCode);
    void OnUploadProgress( qint64 bytesSent, qint64 bytesTotal );
private:
    Ui::HttpUpload *ui;

    QNetworkAccessManager * _pUploadManager = nullptr;
    QNetworkReply * _pReply = nullptr;
};
#endif // HTTPUPLOAD_H

4 获取上传文件及动图

   要上传文件,先在窗口上的 URL编辑框 里输入上传的文件地址(可以使用Ctrl+V组合键粘贴URL地址),或者点击 选择上传的文件按钮,选择需要上传的文件, 选择上传的文件按钮代码如下:

void HttpUpload::on_pushButton_selectUploadFile_clicked()
{
    QFileDialog *fileDialog = new QFileDialog(this);
    //定义文件对话框标题
    fileDialog->setWindowTitle(QStringLiteral("选中文件"));
    //设置默认文件路径
    fileDialog->setDirectory(".");
    //设置文件过滤器
    fileDialog->setNameFilter(tr("File(*.*)"));
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    fileDialog->setFileMode(QFileDialog::ExistingFiles);
    //设置视图模式
    fileDialog->setViewMode(QFileDialog::Detail);
    //打印所有选择的文件的路径
    QStringList fileNames;
    if (fileDialog->exec()) {
        fileNames = fileDialog->selectedFiles();
    }

    //如果选择的文件不为空则显示到界面上
    if(!fileNames.isEmpty())
    {
        ui->lineEdit->setText(fileNames.first());
    }
}

   效果图如下:

在这里插入图片描述
   选择相应文件后,单击 开始上传 按钮开始上传过程, 开始上传 按钮的响应代码如下:

5 QByteArray上传方式,仅供代码参考

void HttpUpload::on_pushButton_startUpload_clicked()
{
    if(_pUploadManager == nullptr)
    {
        _pUploadManager = new QNetworkAccessManager(this);
    }

    QString uploadFileName = ui->lineEdit->text();
    QFile file(uploadFileName);
    if(!file.open(QIODevice::ReadOnly))
    {
        qWarning("file open fail");

        return;
    }

    QByteArray byteFileData = file.readAll();

    file.close();
    QString  uploadUrl = ui->lineEdit_UploadURL->text();
    QUrl url(uploadUrl+"?filename="+file.fileName());

    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");

     _pReply = _pUploadManager->post(request, byteFileData);

    connect(_pReply, &QNetworkReply::finished,this, &HttpUpload::onUpLoadFinished);
    connect(_pReply, SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(onUpLoadError(QNetworkReply::NetworkError)));
    connect(_pReply, SIGNAL(uploadProgress(qint64 ,qint64)), this, SLOT(OnUploadProgress(qint64 ,qint64)));
}

   这种方式要有对应的服务端接收,一般模式是采用表单方式,所以很少支持这种,我写的也不支持,所以支持显示一下实现代码,具体使用还是要看QHttpMultiPart 强烈推荐

6 基于QHttpMultiPart实现的上传及动态效果图

   下面是基于 QHttpMultiPart 实现代码:

void HttpUpload::on_pushButton_startUpload_clicked()
{
    if(_pUploadManager == nullptr)
    {
        _pUploadManager = new QNetworkAccessManager(this);
    }

    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);


    QString uploadFileName = ui->lineEdit->text();

    QFileInfo fileInfo(uploadFileName);

    QString fileName = fileInfo.fileName();


    QHttpPart imagePart;
    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data; name=\"uploadfile\";filename=\"%1\"").arg(fileName)));
    QFile *file = new QFile(uploadFileName);
    file->open(QIODevice::ReadOnly);
    imagePart.setBodyDevice(file);
    file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart

    multiPart->append(imagePart);

    QString urlServerStr = ui->lineEdit_UploadURL->text();
    QUrl url(urlServerStr);
    QNetworkRequest request(url);


    _pReply = _pUploadManager->post(request, multiPart);
    multiPart->setParent(_pReply); // delete the multiPart with the reply

    connect(_pReply, &QNetworkReply::finished,this, &HttpUpload::onUpLoadFinished);
    connect(_pReply, &QNetworkReply::uploadProgress, this, &HttpUpload::OnUploadProgress);
}

   看上传效果图:
在这里插入图片描述
    因为我是本地搭建的HTTP文件服务器, 服务端指定位置上图的文件夹位置,所以可以看到,上传成功后,是有响应的,而且文件也是成功被上传到指定文件夹。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值