From 90b21d40cfe22fd944190881e2489277fc675d69 Mon Sep 17 00:00:00 2001 From: momen Date: Thu, 12 Jun 2025 09:23:28 +0800 Subject: [PATCH] =?UTF-8?q?chore:=E6=9B=B4=E6=96=B0=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E6=9D=A1=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/appdelegate.cpp | 91 +++++++++++++++++------------------------ src/appdelegate.h | 10 +++-- src/downloadmanager.cpp | 70 ++++++++++++++++--------------- src/downloadmanager.h | 14 +++---- 4 files changed, 87 insertions(+), 98 deletions(-) diff --git a/src/appdelegate.cpp b/src/appdelegate.cpp index f211bf7..095b571 100644 --- a/src/appdelegate.cpp +++ b/src/appdelegate.cpp @@ -9,17 +9,22 @@ AppDelegate::AppDelegate(QObject *parent) : QStyledItemDelegate(parent), m_downloadManager(new DownloadManager(this)) { - connect(m_downloadManager, &DownloadManager::downloadProgress, this, [this](int progress) { - m_progress = progress; - emit updateDisplay(); // 触发重绘 + connect(m_downloadManager, &DownloadManager::downloadProgress, this, [this](const QString &packageName, int progress) { + if (m_downloads.contains(packageName)) { + m_downloads[packageName].progress = progress; + emit updateDisplay(); // 触发重绘 + } }); - connect(m_downloadManager, &DownloadManager::downloadFinished, this, [this](bool success) { - m_isDownloading = false; - emit updateDisplay(); // 触发重绘 - if (success) { - qDebug() << "下载完成"; - } else { - qDebug() << "下载失败"; + + connect(m_downloadManager, &DownloadManager::downloadFinished, this, [this](const QString &packageName, bool success) { + if (m_downloads.contains(packageName)) { + m_downloads[packageName].isDownloading = false; + emit updateDisplay(); // 触发重绘 + if (success) { + qDebug() << "下载完成:" << packageName; + } else { + qDebug() << "下载失败:" << packageName; + } } }); } @@ -83,33 +88,27 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c // QString("更新说明:%1\n包大小:%2").arg(description, size)); QString("包大小:%1 MB").arg(QString::number(size.toDouble() / (1024 * 1024), 'f', 2))); - if (m_isDownloading) { - // 进度条 + QString packageName = index.data(Qt::UserRole + 1).toString(); + bool isDownloading = m_downloads.contains(packageName) && m_downloads[packageName].isDownloading; + int progress = m_downloads.value(packageName, DownloadInfo{0, false}).progress; + if (isDownloading) { + // 进度条区域 QRect progressRect(rect.right() - 180, rect.top() + (rect.height() - 20) / 2, 100, 20); QStyleOptionProgressBar progressBarOption; progressBarOption.rect = progressRect; progressBarOption.minimum = 0; progressBarOption.maximum = 100; - progressBarOption.progress = m_progress; - progressBarOption.text = QString("%1%").arg(m_progress); + progressBarOption.progress = progress; + progressBarOption.text = QString("%1%").arg(progress); progressBarOption.textVisible = true; QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); - - // 取消按钮 - QRect cancelButtonRect(rect.right() - 70, rect.top() + (rect.height() - 20) / 2, 60, 20); - QStyleOptionButton cancelButtonOption; - cancelButtonOption.rect = cancelButtonRect; - cancelButtonOption.text = "取消"; - cancelButtonOption.state |= QStyle::State_Enabled; - QApplication::style()->drawControl(QStyle::CE_PushButton, &cancelButtonOption, painter); } else { - // 更新按钮 - QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); - painter->setPen(Qt::NoPen); - painter->setBrush(QColor("#267AFF")); - painter->drawRoundedRect(buttonRect, 6, 6); - painter->setPen(Qt::white); - painter->drawText(buttonRect, Qt::AlignCenter, "更新"); + // 新增:绘制更新按钮 + QStyleOptionButton buttonOption; + buttonOption.rect = QRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); + buttonOption.text = "更新"; + buttonOption.state = QStyle::State_Enabled; + QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter); } painter->restore(); @@ -125,46 +124,30 @@ bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QS if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent *mouseEvent = static_cast(event); QRect rect = option.rect; - if (m_isDownloading) { + QString packageName = index.data(Qt::UserRole + 1).toString(); + + if (m_downloads.contains(packageName) && m_downloads[packageName].isDownloading) { // 取消按钮区域 QRect cancelButtonRect(rect.right() - 70, rect.top() + (rect.height() - 20) / 2, 60, 20); if (cancelButtonRect.contains(mouseEvent->pos())) { - m_isDownloading = false; - emit updateDisplay(); // 触发重绘 + m_downloadManager->cancelDownload(packageName); + m_downloads.remove(packageName); + emit updateDisplay(); return true; } } else { // 更新按钮区域 QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); if (buttonRect.contains(mouseEvent->pos())) { - QString packageName = index.data(Qt::UserRole + 1).toString(); QString downloadUrl = index.data(Qt::UserRole + 7).toString(); QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName); - m_isDownloading = true; - m_progress = 0; - - connect(m_downloadManager, &DownloadManager::downloadProgress, this, [this](int progress) { - m_progress = progress; - emit updateDisplay(); // 更新界面显示 - }); - - connect(m_downloadManager, &DownloadManager::downloadFinished, this, [this](bool success) { - m_isDownloading = false; - emit updateDisplay(); // 更新界面显示 - if (success) { - qDebug() << "下载完成"; - } else { - qDebug() << "下载失败"; - } - }); - - m_downloadManager->startDownload(downloadUrl, outputPath); - emit updateDisplay(); // 触发重绘 + m_downloads[packageName] = {0, true}; + m_downloadManager->startDownload(packageName, downloadUrl, outputPath); + emit updateDisplay(); return true; } } - qDebug() << "点击了第" << index.row() << "行"; } return QStyledItemDelegate::editorEvent(event, model, option, index); } \ No newline at end of file diff --git a/src/appdelegate.h b/src/appdelegate.h index 11c78bf..4afa130 100644 --- a/src/appdelegate.h +++ b/src/appdelegate.h @@ -23,9 +23,13 @@ signals: void updateDisplay(); // 声明更新显示的信号 private: - DownloadManager *m_downloadManager; // 声明下载管理器指针 - int m_progress = 0; // 声明下载进度 - bool m_isDownloading = false; // 声明下载状态 + struct DownloadInfo { + int progress = 0; + bool isDownloading = false; + }; + QHash m_downloads; // 使用包名作为键的下载状态 + DownloadManager *m_downloadManager; + }; #endif // APPDELEGATE_H diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 1603928..cef9fb5 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -6,46 +6,50 @@ DownloadManager::DownloadManager(QObject *parent) : QObject(parent) {} -void DownloadManager::startDownload(const QString &url, const QString &outputPath) +void DownloadManager::startDownload(const QString &packageName, const QString &url, const QString &outputPath) { - QString metalinkUrl = url + ".metalink"; // 构造 Metalink URL - qDebug() << "开始下载 Metalink 文件:" << metalinkUrl; - + QString metalinkUrl = url + ".metalink"; QStringList arguments; - arguments << "--enable-rpc=false" << "--console-log-level=warn" - << "--summary-interval=1" << "--dir=" + QFileInfo(outputPath).absolutePath() - << "--out=" + QFileInfo(outputPath).fileName() << metalinkUrl; + arguments << "--enable-rpc=false" + << "--console-log-level=warn" + << "--summary-interval=1" + << "--dir=" + QFileInfo(outputPath).absolutePath() + << "--out=" + QFileInfo(outputPath).fileName() + << metalinkUrl; - connect(&m_aria2Process, &QProcess::readyReadStandardOutput, this, &DownloadManager::onAria2Progress); - connect(&m_aria2Process, QOverload::of(&QProcess::finished), this, &DownloadManager::onAria2Finished); + QProcess* process = new QProcess(this); + m_processes.insert(packageName, process); - m_aria2Process.start("aria2c", arguments); -} - -void DownloadManager::onAria2Progress() -{ - QString output = m_aria2Process.readAllStandardOutput(); - QRegularExpression regex(R"(\((\d+)%\))"); - QRegularExpressionMatchIterator i = regex.globalMatch(output); - - while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); - if (match.hasMatch()) { - int progress = match.captured(1).toInt(); - emit downloadProgress(progress); // 发送进度信号 - qDebug() << "下载进度:" << progress << "%"; + connect(process, &QProcess::readyReadStandardOutput, [this, process, packageName]() { + QString output = process->readAllStandardOutput(); + QRegularExpression regex(R"(\((\d+)%\))"); + QRegularExpressionMatchIterator i = regex.globalMatch(output); + while (i.hasNext()) { + QRegularExpressionMatch match = i.next(); + if (match.hasMatch()) { + int progress = match.captured(1).toInt(); + emit downloadProgress(packageName, progress); + qDebug() << "下载进度:" << progress << "%"; + } } - } + }); + + connect(process, QOverload::of(&QProcess::finished), + [this, packageName](int exitCode, QProcess::ExitStatus exitStatus) { + bool success = (exitCode == 0 && exitStatus == QProcess::NormalExit); + emit downloadFinished(packageName, success); + m_processes.remove(packageName); + }); + + process->start("aria2c", arguments); } - -void DownloadManager::onAria2Finished(int exitCode, QProcess::ExitStatus exitStatus) +void DownloadManager::cancelDownload(const QString &packageName) { - if (exitCode == 0 && exitStatus == QProcess::NormalExit) { - qDebug() << "下载完成"; - emit downloadFinished(true); // 发送完成信号 - } else { - qWarning() << "下载失败,退出代码:" << exitCode; - emit downloadFinished(false); // 发送失败信号 + if (m_processes.contains(packageName)) { + QProcess* process = m_processes[packageName]; + process->terminate(); + process->waitForFinished(); + m_processes.remove(packageName); } } diff --git a/src/downloadmanager.h b/src/downloadmanager.h index ca80330..362867d 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -11,18 +11,16 @@ class DownloadManager : public QObject Q_OBJECT public: explicit DownloadManager(QObject *parent = nullptr); - void startDownload(const QString &url, const QString &outputPath); + void startDownload(const QString &packageName, const QString &url, const QString &outputPath); // 修改参数列表 + void cancelDownload(const QString &packageName); // 移动到public区域 signals: - void downloadProgress(int progress); // 下载进度信号 - void downloadFinished(bool success); // 下载完成信号 - -private slots: - void onAria2Progress(); // 处理 aria2 的进度 - void onAria2Finished(int exitCode, QProcess::ExitStatus exitStatus); // 处理 aria2 完成事件 + void downloadProgress(const QString &packageName, int progress); + void downloadFinished(const QString &packageName, bool success); private: - QProcess m_aria2Process; // 用于运行 aria2 的进程 + QHash m_processes; // 移除旧的m_aria2Process + // 移除旧的onAria2Progress和onAria2Finished声明 }; #endif // DOWNLOADMANAGER_H