chore:更新下载进度条显示

This commit is contained in:
2025-06-12 09:23:28 +08:00
parent e416ffdbff
commit 90b21d40cf
4 changed files with 87 additions and 98 deletions

View File

@@ -9,17 +9,22 @@
AppDelegate::AppDelegate(QObject *parent) : QStyledItemDelegate(parent), m_downloadManager(new DownloadManager(this)) AppDelegate::AppDelegate(QObject *parent) : QStyledItemDelegate(parent), m_downloadManager(new DownloadManager(this))
{ {
connect(m_downloadManager, &DownloadManager::downloadProgress, this, [this](int progress) { connect(m_downloadManager, &DownloadManager::downloadProgress, this, [this](const QString &packageName, int progress) {
m_progress = progress; if (m_downloads.contains(packageName)) {
emit updateDisplay(); // 触发重绘 m_downloads[packageName].progress = progress;
emit updateDisplay(); // 触发重绘
}
}); });
connect(m_downloadManager, &DownloadManager::downloadFinished, this, [this](bool success) {
m_isDownloading = false; connect(m_downloadManager, &DownloadManager::downloadFinished, this, [this](const QString &packageName, bool success) {
emit updateDisplay(); // 触发重绘 if (m_downloads.contains(packageName)) {
if (success) { m_downloads[packageName].isDownloading = false;
qDebug() << "下载完成"; emit updateDisplay(); // 触发重绘
} else { if (success) {
qDebug() << "下载失败"; 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\n包大小%2").arg(description, size));
QString("包大小:%1 MB").arg(QString::number(size.toDouble() / (1024 * 1024), 'f', 2))); 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); QRect progressRect(rect.right() - 180, rect.top() + (rect.height() - 20) / 2, 100, 20);
QStyleOptionProgressBar progressBarOption; QStyleOptionProgressBar progressBarOption;
progressBarOption.rect = progressRect; progressBarOption.rect = progressRect;
progressBarOption.minimum = 0; progressBarOption.minimum = 0;
progressBarOption.maximum = 100; progressBarOption.maximum = 100;
progressBarOption.progress = m_progress; progressBarOption.progress = progress;
progressBarOption.text = QString("%1%").arg(m_progress); progressBarOption.text = QString("%1%").arg(progress);
progressBarOption.textVisible = true; progressBarOption.textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); 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 { } else {
// 更新按钮 // 新增:绘制更新按钮
QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); QStyleOptionButton buttonOption;
painter->setPen(Qt::NoPen); buttonOption.rect = QRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30);
painter->setBrush(QColor("#267AFF")); buttonOption.text = "更新";
painter->drawRoundedRect(buttonRect, 6, 6); buttonOption.state = QStyle::State_Enabled;
painter->setPen(Qt::white); QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
painter->drawText(buttonRect, Qt::AlignCenter, "更新");
} }
painter->restore(); painter->restore();
@@ -125,46 +124,30 @@ bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QS
if (event->type() == QEvent::MouseButtonRelease) { if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
QRect rect = option.rect; 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); QRect cancelButtonRect(rect.right() - 70, rect.top() + (rect.height() - 20) / 2, 60, 20);
if (cancelButtonRect.contains(mouseEvent->pos())) { if (cancelButtonRect.contains(mouseEvent->pos())) {
m_isDownloading = false; m_downloadManager->cancelDownload(packageName);
emit updateDisplay(); // 触发重绘 m_downloads.remove(packageName);
emit updateDisplay();
return true; return true;
} }
} else { } else {
// 更新按钮区域 // 更新按钮区域
QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30); QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30);
if (buttonRect.contains(mouseEvent->pos())) { if (buttonRect.contains(mouseEvent->pos())) {
QString packageName = index.data(Qt::UserRole + 1).toString();
QString downloadUrl = index.data(Qt::UserRole + 7).toString(); QString downloadUrl = index.data(Qt::UserRole + 7).toString();
QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName); QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName);
m_isDownloading = true; m_downloads[packageName] = {0, true};
m_progress = 0; m_downloadManager->startDownload(packageName, downloadUrl, outputPath);
emit updateDisplay();
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(); // 触发重绘
return true; return true;
} }
} }
qDebug() << "点击了第" << index.row() << "";
} }
return QStyledItemDelegate::editorEvent(event, model, option, index); return QStyledItemDelegate::editorEvent(event, model, option, index);
} }

View File

@@ -23,9 +23,13 @@ signals:
void updateDisplay(); // 声明更新显示的信号 void updateDisplay(); // 声明更新显示的信号
private: private:
DownloadManager *m_downloadManager; // 声明下载管理器指针 struct DownloadInfo {
int m_progress = 0; // 声明下载进度 int progress = 0;
bool m_isDownloading = false; // 声明下载状态 bool isDownloading = false;
};
QHash<QString, DownloadInfo> m_downloads; // 使用包名作为键的下载状态
DownloadManager *m_downloadManager;
}; };
#endif // APPDELEGATE_H #endif // APPDELEGATE_H

View File

@@ -6,46 +6,50 @@
DownloadManager::DownloadManager(QObject *parent) : QObject(parent) {} 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 QString metalinkUrl = url + ".metalink";
qDebug() << "开始下载 Metalink 文件:" << metalinkUrl;
QStringList arguments; QStringList arguments;
arguments << "--enable-rpc=false" << "--console-log-level=warn" arguments << "--enable-rpc=false"
<< "--summary-interval=1" << "--dir=" + QFileInfo(outputPath).absolutePath() << "--console-log-level=warn"
<< "--out=" + QFileInfo(outputPath).fileName() << metalinkUrl; << "--summary-interval=1"
<< "--dir=" + QFileInfo(outputPath).absolutePath()
<< "--out=" + QFileInfo(outputPath).fileName()
<< metalinkUrl;
connect(&m_aria2Process, &QProcess::readyReadStandardOutput, this, &DownloadManager::onAria2Progress); QProcess* process = new QProcess(this);
connect(&m_aria2Process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &DownloadManager::onAria2Finished); m_processes.insert(packageName, process);
m_aria2Process.start("aria2c", arguments); connect(process, &QProcess::readyReadStandardOutput, [this, process, packageName]() {
} QString output = process->readAllStandardOutput();
QRegularExpression regex(R"(\((\d+)%\))");
void DownloadManager::onAria2Progress() QRegularExpressionMatchIterator i = regex.globalMatch(output);
{ while (i.hasNext()) {
QString output = m_aria2Process.readAllStandardOutput(); QRegularExpressionMatch match = i.next();
QRegularExpression regex(R"(\((\d+)%\))"); if (match.hasMatch()) {
QRegularExpressionMatchIterator i = regex.globalMatch(output); int progress = match.captured(1).toInt();
emit downloadProgress(packageName, progress);
while (i.hasNext()) { qDebug() << "下载进度:" << progress << "%";
QRegularExpressionMatch match = i.next(); }
if (match.hasMatch()) {
int progress = match.captured(1).toInt();
emit downloadProgress(progress); // 发送进度信号
qDebug() << "下载进度:" << progress << "%";
} }
} });
connect(process, QOverload<int, QProcess::ExitStatus>::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::cancelDownload(const QString &packageName)
void DownloadManager::onAria2Finished(int exitCode, QProcess::ExitStatus exitStatus)
{ {
if (exitCode == 0 && exitStatus == QProcess::NormalExit) { if (m_processes.contains(packageName)) {
qDebug() << "下载完成"; QProcess* process = m_processes[packageName];
emit downloadFinished(true); // 发送完成信号 process->terminate();
} else { process->waitForFinished();
qWarning() << "下载失败,退出代码:" << exitCode; m_processes.remove(packageName);
emit downloadFinished(false); // 发送失败信号
} }
} }

View File

@@ -11,18 +11,16 @@ class DownloadManager : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit DownloadManager(QObject *parent = nullptr); 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: signals:
void downloadProgress(int progress); // 下载进度信号 void downloadProgress(const QString &packageName, int progress);
void downloadFinished(bool success); // 下载完成信号 void downloadFinished(const QString &packageName, bool success);
private slots:
void onAria2Progress(); // 处理 aria2 的进度
void onAria2Finished(int exitCode, QProcess::ExitStatus exitStatus); // 处理 aria2 完成事件
private: private:
QProcess m_aria2Process; // 用于运行 aria2 的进程 QHash<QString, QProcess*> m_processes; // 移除旧的m_aria2Process
// 移除旧的onAria2Progress和onAria2Finished声明
}; };
#endif // DOWNLOADMANAGER_H #endif // DOWNLOADMANAGER_H