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))
{
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<QMouseEvent*>(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);
}

View File

@@ -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<QString, DownloadInfo> m_downloads; // 使用包名作为键的下载状态
DownloadManager *m_downloadManager;
};
#endif // APPDELEGATE_H

View File

@@ -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<int, QProcess::ExitStatus>::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<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::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);
}
}

View File

@@ -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<QString, QProcess*> m_processes; // 移除旧的m_aria2Process
// 移除旧的onAria2Progress和onAria2Finished声明
};
#endif // DOWNLOADMANAGER_H