Window下基于QT+阿里OSS编写一个客户端

主要技术

1.QT访问阿里OSS,C++接口
2.QT动态控件
3.表格中显示控
4.动态显示阿里文件下载进度
3.QT PRI项目管理思路

设计步骤:

1.基于MINGW编译aliyun-oss-cpp-sdk,生成libalibabacloud-oss-cpp-sdk.a
参考:https://blog.csdn.net/pengrui18/article/details/106903464
2.新建QT项目及PRI子项目
略过
3.将libalibabacloud-oss-cpp-sdk.a及相关库文件加入子项目
略过
4.编写界面显示
阿里云链接部分(这部分代码参考网上的,改了一个接口函数download_files_to_memory() ):

alibabacloud_handle.cpp

#include "alibabacloud_handle.h"
#include <unistd.h>
#include <string.h>
namespace ALIBABACLOUD_HANDLE{

alibabacloud_handle::alibabacloud_handle(const std::string &AccessKeyId,const std::string &AccessKeySecret,const std::string &Endpoint,const std::string &BucketName):AccessKeyId(AccessKeyId),AccessKeySecret(AccessKeySecret),Endpoint(Endpoint),BucketName(BucketName)
{

    InitializeSdk();

    /* 设置连接池数,默认为16个 */
    conf.maxConnections = 20;

    /* 设置请求超时时间,超时没有收到数据就关闭连接,默认为10000ms */
    conf.requestTimeoutMs = 8000;

    /* 设置建立连接的超时时间,默认为5000ms */
    conf.connectTimeoutMs = 8000;

    oss_client = new OssClient(Endpoint, AccessKeyId, AccessKeySecret, conf);
    if(oss_client == NULL){
        status = -1;
        return;
    }else{
		status = 1;
	}

    auto callback = std::bind(&alibabacloud_handle::ProgressCallback,this,
        std::placeholders::_1,
        std::placeholders::_2,
        std::placeholders::_3,
        std::placeholders::_4
    );
    progressCallback = {  callback , this };

}

alibabacloud_handle::~alibabacloud_handle(){
    ShutdownSdk();
}

bool alibabacloud_handle:: upload_files(const std::string &target_path, const std::string &local_path){

    std::shared_ptr<std::iostream> content = std::make_shared<std::fstream>(local_path.c_str(), std::ios::in|std::ios::binary);
    PutObjectRequest request(BucketName, target_path, content);

    request.setTransferProgress(progressCallback);
    auto outcome = oss_client->PutObject(request);

    if (!outcome.isSuccess()) {
        /* 异常处理 */
        std::cout << "PutObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return false;
    }
    return true;
}


bool alibabacloud_handle::query_directory(const std::string &target_directory, std::vector<file_detail_st> &details){
    std::string nextMarker = "";

	ListObjectsRequest request1(BucketName);
	auto outcome = oss_client->ListObjects(request1);
    do {
        /* 列举文件 */
        ListObjectsRequest request(BucketName);
         /* 设置正斜线(/)为文件夹的分隔符 */
        request.setDelimiter("/");
        request.setPrefix(target_directory);
        request.setMarker(nextMarker);
        outcome = oss_client->ListObjects(request);

        if (!outcome.isSuccess ()) {    
            /* 异常处理 */
            std::cout << "ListObjects fail" <<
            ",code:" << outcome.error().Code() <<
            ",message:" << outcome.error().Message() <<
            ",requestId:" << outcome.error().RequestId() << std::endl;
            return false;
        }  
        for (const auto& object : outcome.result().ObjectSummarys()) {
            file_detail_st detail;
//            std::cout << "object"<<
//            ",name:" << object.Key() <<
//            " ,size:" << object.Size() <<
//            " ,lastmodify time:" << object.LastModified() << std::endl;
            detail.name = object.Key();
            detail.size = std::to_string(object.Size());
            detail.date = object.LastModified();
            details.push_back(detail);
        }
        for (const auto& commonPrefix : outcome.result().CommonPrefixes()) {
            std::cout << "commonPrefix" << ",name:" << commonPrefix << std::endl;
        }
        nextMarker = outcome.result().NextMarker();
    } while (outcome.result().IsTruncated());


    return true;
}

bool alibabacloud_handle::download_files(const std::string &target_directory,const std::string &local_directory){

    DownloadObjectRequest request(BucketName, target_directory, local_directory);
    request.setTransferProgress(progressCallback);

    auto outcome = oss_client->ResumableDownloadObject(request);
  
    if (!outcome.isSuccess()) {
        /* 异常处理 */
        std::cout << "ResumableDownloadObject fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return false;
    }else{
        return true;
    }
    
}


void alibabacloud_handle::ProgressCallback(size_t increment, int64_t transfered, int64_t total, void* userData) const
{
    alibabacloud_handle *handle_ptr = (alibabacloud_handle *)userData;
    int i = (int)((transfered*1.0/total*1.0) *100);
//    printf("[%d%%][%c]\r", i , lable[i % 4]);
//    fflush(stdout);
    handle_ptr->download_percent = i;
}

bool alibabacloud_handle::download_files_to_memory(const std::string &target_directory,std::string &buf){
    std::string strcontent;
    GetObjectRequest request(BucketName, target_directory);

    request.setTransferProgress(progressCallback);

    auto outcome = oss_client->GetObject(request);
    if (outcome.isSuccess()) { 
        std::cout << "getObjectToBuffer" << " success, Content-Length:" << outcome.result().Metadata().ContentLength() << std::endl;
        //*(outcome.result().Content()) >> buf;

//        *(outcome.result().Content())->getline()
        getline(*(outcome.result().Content()), buf, '\0');
    }
    else {
        /*异常处理*/
        std::cout << "getObjectToBuffer fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return false;
    }
    return true;
}
}


alibabacloud_handle.h

#pragma once

#include <string>
#include <stdio.h>
#include <alibabacloud/oss/OssClient.h>
#include <memory>
#include <fstream>
#include <iostream>
using namespace AlibabaCloud::OSS;

namespace ALIBABACLOUD_HANDLE{

struct file_detail_st
{
    std::string name;
    std::string size;
    std::string date;
};

class alibabacloud_handle{
public:
    // desc: 构造函数用于初始化OSS账号信息以及初始化sdk
	// param: 参数一/AccessKeyId 参数二/AccessKeySecret 参数三/Endpoint 参数四/BucketName 
	// return: NULL
    alibabacloud_handle(const std::string &,const std::string &,const std::string &,const std::string &);

    // desc: 关闭sdk
	// param: NULL 
	// return: NULL
    ~alibabacloud_handle();
    
    int get_download_percent() {return download_percent;}
    // desc: 上传文件
	// param: 参数一/阿里云上的路径及要保存的文件名 参数二/本地路径 
	// return: 成功返回true,失败返回false
    bool upload_files(const std::string &,const std::string &);

    // desc: 查询阿里云某路径下的文件列表
    // param: 参数一/阿里云上的路径 参数二/文件列表
	// return: 成功返回true,失败返回false
    bool query_directory(const std::string &, std::vector<file_detail_st> &);

    // desc: 下载文件到本地路径下
	// param: 参数一/阿里云上的路径及要保存的文件名 参数二/本地路径
	// return: 成功返回true,失败返回false
    bool download_files(const std::string &,const std::string &);

    // desc: 下载文件到内存中
	// param: 参数一/阿里云上的路径及要保存的文件名 参数二/保存数据的字符串
	// return: 成功返回true,失败返回false
    bool download_files_to_memory(const std::string &,std::string &);

    // desc: 进度条显示
	// param: transfered/已完成的大小 total/总大小 
	// return: NULL
    void ProgressCallback(size_t increment, int64_t transfered, int64_t total, void* userData) const;

public:
    int status;

private:
    //OSS 通过使用 AccessKeyId 和 AccessKeySecret 对称加密的方法来验证某个请求的发送者身份。AccessKeyId 用于标识用户;AccessKeySecret 是用户用于加密签名字符串和 OSS 用来验证签名字符串的密钥,必须保密。
    std::string AccessKeyId;
    std::string AccessKeySecret;
    std::string Endpoint;       //OSS对外服务的访问域名
    std::string BucketName;     //存储空间名
    ClientConfiguration conf;
    OssClient *oss_client;
    TransferProgress progressCallback;
    const char lable[5] = {'|','/','-','\\','\\'};

    //Download Percent
    int download_percent;
};
}

动态控件及tableWidget显示控件:


void frmAptest::UpdateTableWidget(int type)
{
    if (ossdatas.size() > 31)
    {
        return ;
    }

    ui->tableWidget->clearContents();

//    ui->tableWidget->setRowCount(32);
//    ui->tableWidget->setColumnCount(7);

    osswidgets.clear();
    for (int index = 0; index < 32; index++)
    {
        OSSWidget widget;

        widget.label_num_ptr = new QLabel("test");
        widget.label_filename_ptr = new QLabel("test");
        widget.label_filesize_ptr = new QLabel("test");
        widget.label_filedate_ptr = new QLabel("test");

        widget.btn_download_ptr = new QPushButton("下载");
        widget.btn_download_ptr->setObjectName(QString("btn_download%1").arg(index));
        widget.progress_download_ptr =  new QProgressBar();
        if (type == 1)
        {
            widget.btn_download_ptr->setEnabled(true);
            widget.progress_download_ptr->setEnabled(true);
        } else {
            widget.btn_download_ptr->setEnabled(false);
            widget.progress_download_ptr->setEnabled(false);
        }


        widget.btn_handle_ptr = new QPushButton("接管分析");
        widget.btn_handle_ptr->setObjectName(QString("btn_handle_%1").arg(index));
        widget.progress_handle_ptr =  new QProgressBar();
        if (type == 1)
        {
            widget.btn_handle_ptr->setEnabled(false);
            widget.progress_handle_ptr->setEnabled(false);
        } else {
            widget.btn_handle_ptr->setEnabled(true);
            widget.progress_handle_ptr->setEnabled(true);
        }


        connect(widget.btn_download_ptr, SIGNAL(clicked()), this, SLOT(slot_btn_clicked()));
        connect(widget.btn_handle_ptr, SIGNAL(clicked()), this, SLOT(slot_btn_handle_clicked()));
        osswidgets.push_back(widget);
    }

    oss_mutex_.lock();
    for (int index=0; index < ossdatas.size(); index++)
    {
        osswidgets[index].label_num_ptr->setText(QString("%1").arg(ossdatas[index].seqnum));
        osswidgets[index].label_num_ptr->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        osswidgets[index].label_filename_ptr->setText(QString::fromStdString(ossdatas[index].filename));
        osswidgets[index].label_filename_ptr->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        osswidgets[index].label_filesize_ptr->setText(QString::fromStdString(ossdatas[index].filesize));
        osswidgets[index].label_filesize_ptr->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        osswidgets[index].label_filedate_ptr->setText(QString::fromStdString(ossdatas[index].filedate));
        osswidgets[index].label_filedate_ptr->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

        if (ossdatas[index].download_status == 1)
        {
            osswidgets[index].progress_download_ptr->setValue(100);
        } else if (ossdatas[index].download_status == 2) {
            osswidgets[index].progress_download_ptr->setValue(0);
            osswidgets[index].progress_handle_ptr->setStyleSheet("QProgressBar::chunk { background-color: rgb(255, 0, 0) }");
        } else {
            osswidgets[index].progress_download_ptr->setValue(0);
        }

        if (ossdatas[index].handle_status)
        {
            osswidgets[index].progress_handle_ptr->setValue(100);
        } else {
            osswidgets[index].progress_handle_ptr->setValue(0);
        }
        ui->tableWidget->setCellWidget(index, 0, osswidgets[index].label_num_ptr);
        ui->tableWidget->setCellWidget(index, 1, osswidgets[index].label_filename_ptr);
        ui->tableWidget->setCellWidget(index, 2, osswidgets[index].label_filesize_ptr);
        ui->tableWidget->setCellWidget(index, 3, osswidgets[index].label_filedate_ptr);
        //btn_download center show
        QWidget *btn_download_widget_ptr = new QWidget;
        QHBoxLayout *layout = new QHBoxLayout;
        layout->setSpacing(0);
        layout->setMargin(0);
        layout->addWidget(osswidgets[index].btn_download_ptr);
        btn_download_widget_ptr->setLayout(layout);
        ui->tableWidget->setCellWidget(index, 4, btn_download_widget_ptr);
        ui->tableWidget->setCellWidget(index, 5, osswidgets[index].progress_download_ptr);
        // btn_analyse center view.
        QWidget *btn_analsye_widget_ptr = new QWidget;
        QHBoxLayout *layout_analyse = new QHBoxLayout;
        layout_analyse->setSpacing(0);
        layout_analyse->setMargin(0);
        layout_analyse->addWidget(osswidgets[index].btn_handle_ptr);
        btn_analsye_widget_ptr->setLayout(layout_analyse);
        ui->tableWidget->setCellWidget(index, 6, btn_analsye_widget_ptr);
        ui->tableWidget->setCellWidget(index, 7, osswidgets[index].progress_handle_ptr);

    }
    oss_mutex_.unlock();
}

进度条显示下载百分比:

##########################下载开始,设置状态###################################
    if ("btn_download0" == btn_ptr->objectName())
    {

//        QString path = QCoreApplication::applicationDirPath();

        std::string remote_directory = ossdatas[0].filename;
        std::string local_directory = pathname + "/temp/" + ossdatas[0].filename;
        std::size_t pos = ossdatas[0].filename.find("/", 0);//.find(vehicleid, 0);
        local_filename = path.toStdString() + "/" + ossdatas[0].filename.substr(pos + 1);

        ossdatas[0].is_downloading = 1;

        std::thread([this, local_filename, remote_directory]() {
            if (handle_ptr->download_files(remote_directory, local_filename))
            {
//                ossdatas[0].is_downloading = false;
                ossdatas[0].download_status = 1;
//                osswidgets[0].progress_download_ptr->setValue(100);
            } else {
//                ossdatas[0].is_downloading = false;
                ossdatas[0].download_status = 2;
//                osswidgets[0].progress_download_ptr->setValue(0);
            }
        }).detach();
    }
##########################显示部分,定时器取进度数据并显示状态###################################
	void frmAptest::slot_timeout()
{
    int i = 0;
    for (i=0; i < ossdatas.size(); i++)
    {
        if (ossdatas[i].is_downloading == 1)
        {
            break;
        }

    }
    if (i < ossdatas.size())
    {
        if (ossdatas[i].download_status == 1)
        {
            osswidgets[i].progress_download_ptr->setValue(handle_ptr->get_download_percent());
            if (handle_ptr->get_download_percent() >= 100)
            {
                ossdatas[i].is_downloading = false;
            }
        } else if (ossdatas[i].download_status == 2) {
            ossdatas[i].is_downloading = false;
            ossdatas[i].download_status = 0;
            osswidgets[i].progress_download_ptr->setValue(100);
            osswidgets[i].progress_download_ptr->setStyleSheet("QProgressBar::chunk{background:red}");
        }
    }

    for (i=0; i < ossdatas.size(); i++)
    {
        if (ossdatas[i].is_handling)
        {
            //std::cout << i << " is_handling" << std::endl;
            break;
        }
    }

    if (i < ossdatas.size())
    {
        if (ossdatas[i].handle_status == 1)
        {
            osswidgets[i].progress_handle_ptr->setValue(handle_ptr->get_download_percent());
            if (handle_ptr->get_download_percent() >= 100)
            {
//                std::cout << i << " is_handling ok" << std::endl;
                ossdatas[i].is_handling = false;
            }
            ossdatas[i].handle_status = 0;
        } else if (ossdatas[i].handle_status == 2) {
            ossdatas[i].is_handling = false;
            ossdatas[i].handle_status = 0;
            osswidgets[i].progress_handle_ptr->setValue(100);
            osswidgets[i].progress_handle_ptr->setStyleSheet("QProgressBar::chunk{background:red}");
        }

    }
}

效果图

在这里插入图片描述
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章