#include "downloadlistwidget.h" #include "ui_downloadlistwidget.h" #include "widgets/common/downloaditem.h" #include "backend/sparkapi.h" #include "backend/downloadworker.h" #include "utils/utils.h" #include "application.h" #include #include #include DownloadListWidget::DownloadListWidget(QWidget *parent) : DBlurEffectWidget(parent), ui(new Ui::DownloadListWidget) { ui->setupUi(this); setWindowTitle(QObject::tr("Download list")); installEventFilter(this); this->setAttribute(Qt::WA_Hover, true); setFocus(); setFixedSize(500, 400); setMaskAlpha(250); ui->listWidget->hide(); ui->widget->show(); // 计算显示下载速度 download_speed.setInterval(1000); download_speed.start(); connect(&download_speed, &QTimer::timeout, [=]() { if(isdownload && theSpeed == "") { size1 = download_size; double bspeed; bspeed = size1 - size2; if(bspeed < 1024) { theSpeed = QString::number(bspeed) + "B/s"; } else if(bspeed < 1024 * 1024) { theSpeed = QString::number(0.01 * int(100 * (bspeed / 1024))) + "KB/s"; } else if(bspeed < 1024 * 1024 * 1024) { theSpeed = QString::number(0.01 * int(100 * (bspeed / (1024 * 1024)))) + "MB/s"; } else { theSpeed = QString::number(0.01 * int(100 * (bspeed / (1024 * 1024 * 1024)))) + "GB/s"; } size2 = download_size; } if(isdownload){ downloaditemlist[nowDownload - 1]->setSpeed(theSpeed); }else{ emit downloadProgress(0); } }); } DownloadListWidget::~DownloadListWidget() { if (downloadController) { downloadController->disconnect(); downloadController->stopDownload(); // 这里没有释放 downloadController,使用懒汉式单例 } clearItem(); delete ui; } void DownloadListWidget::clearItem() { ui->listWidget->clear(); } DownloadItem* DownloadListWidget::addItem(QString name, QString fileName, QString pkgName, const QPixmap icon, QString downloadurl) { if (fileName.isEmpty()) { return nullptr; } urList.append(downloadurl); allDownload += 1; DownloadItem *di = new DownloadItem; dlist << downloadurl; downloaditemlist << di; di->setName(name); di->setFileName(fileName); di->pkgName = pkgName; di->seticon(icon); QListWidgetItem *pItem = new QListWidgetItem(); pItem->setSizeHint(QSize(240, 56)); // ui 中单个 downloaditem 高度固定 56px(上下 margin 8px,图片固定 48x48) ui->listWidget->addItem(pItem); ui->listWidget->setItemWidget(pItem, di); if (!isBusy) { nowDownload += 1; startRequest(urList.at(nowDownload - 1), fileName); // 进行链接请求 } return di; } QList DownloadListWidget::getDIList() { return downloaditemlist; } QList DownloadListWidget::getUrlList() { return urList; } void DownloadListWidget::startRequest(QUrl url, QString fileName) { ui->listWidget->show(); ui->widget->hide(); isBusy = true; isdownload = true; downloaditemlist[allDownload - 1]->free = false; // 使用懒汉式单例来存储downloadController if (downloadController == nullptr) { downloadController = new DownloadController; // 并发下载,在第一次点击下载按钮的时候才会初始化 } if (downloadController) { downloadController->disconnect(); downloadController->stopDownload(); } connect(downloadController, &DownloadController::downloadProcess, this, &DownloadListWidget::updateDataReadProgress); connect(downloadController, &DownloadController::downloadFinished, this, &DownloadListWidget::httpFinished); // connect(downloadController, &DownloadController::errorOccur, this, [=](QString msg){this->sendNotification(msg);}); downloadController->setFilename(fileName); downloadController->startDownload(url.toString()); } /*************************************************************** * @brief 下载列表完成下载的回调函数 * @param * @note 如果正在安装,则在新开的线程空间中等待上一个安装完 * @Sample usage: **************************************************************/ void DownloadListWidget::httpFinished() // 完成下载 { isdownload = false; isBusy = false; QtConcurrent::run([=]() { while (downloaditemlist[nowDownload - 1]->readyInstall() == -1) { continue; } downloaditemlist[nowDownload - 1]->free = true; emit downloadFinished(); if (nowDownload < allDownload) { // 如果有排队则下载下一个 qDebug() << "切换下一个下载..."; nowDownload += 1; while (downloaditemlist[nowDownload - 1]->close) { nowDownload += 1; if (nowDownload >= allDownload) { nowDownload = allDownload; return; } } QString fileName = downloaditemlist[nowDownload - 1]->getName(); startRequest(urList.at(nowDownload - 1), fileName); } }); } void DownloadListWidget::updateDataReadProgress(QString speedInfo, qint64 bytesRead, qint64 totalBytes) { if (totalBytes <= 0) { return; } theSpeed = speedInfo; downloaditemlist[nowDownload - 1]->setMax(10000); // 最大值 downloaditemlist[nowDownload - 1]->setValue(int(bytesRead * 100 / totalBytes) * 100); // 当前值 emit downloadProgress(int(bytesRead * 100 / totalBytes)); download_size = bytesRead; if (downloaditemlist[nowDownload - 1]->close) { // 随时检测下载是否被取消 downloadController->disconnect(); downloadController->stopDownload(); downloaditemlist[nowDownload - 1]->closeDownload(); httpFinished(); } } void DownloadListWidget::m_move(int x, int y) { m_rect.setX(x); m_rect.setY(y); move(x, y); return; } void DownloadListWidget::mouseMoveEvent(QMouseEvent *event) { setGeometry(m_rect); } void DownloadListWidget::on_pushButton_clicked() { QDesktopServices::openUrl(QUrl("file:///tmp/spark-store", QUrl::TolerantMode)); }