主要技術
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}");
}
}
}
效果圖