chore:更新下载骨架

This commit is contained in:
momen 2025-06-08 10:44:51 +08:00
parent 705478fdf0
commit 2cb69c72f3
5 changed files with 171 additions and 12 deletions

View File

@ -27,6 +27,7 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
icons.qrc
appdelegate.h appdelegate.cpp
applistmodel.h applistmodel.cpp
downloadmanager.h downloadmanager.cpp
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET Spark-Update-Tool APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR

View File

@ -1,9 +1,27 @@
#include "appdelegate.h"
#include <QIcon>
#include <QDebug>
#include "downloadmanager.h"
#include <QProgressBar>
#include <QPushButton>
#include <QApplication> // 包含 QApplication 头文件
AppDelegate::AppDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
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::downloadFinished, this, [this](bool success) {
m_isDownloading = false;
emit updateDisplay(); // 触发重绘
if (success) {
qDebug() << "下载完成";
} else {
qDebug() << "下载失败";
}
});
}
void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
painter->save();
@ -64,18 +82,38 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
// QString("更新说明:%1\n包大小%2").arg(description, size));
QString("包大小:%1").arg(size));
// 更新按钮(样式占位)
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, "更新");
if (m_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.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, "更新");
}
painter->restore();
}
QSize AppDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return QSize(option.rect.width(), 110); // 每行高度 110
@ -84,8 +122,33 @@ QSize AppDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInde
bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
QRect rect = option.rect;
if (m_isDownloading) {
// 取消按钮区域
QRect cancelButtonRect(rect.right() - 70, rect.top() + (rect.height() - 20) / 2, 60, 20);
if (cancelButtonRect.contains(mouseEvent->pos())) {
// 修正方法调用,假设 DownloadManager 有 killProcess 方法
if (m_downloadManager->isRunning()) {
m_downloadManager->killProcess();
m_isDownloading = false;
emit updateDisplay(); // 触发重绘
}
return true;
}
} else {
// 更新按钮区域
QRect buttonRect(rect.right() - 80, rect.top() + (rect.height() - 30) / 2, 70, 30);
if (buttonRect.contains(mouseEvent->pos())) {
QString appName = index.data(Qt::DisplayRole).toString();
m_isDownloading = true;
m_progress = 0;
m_downloadManager->startDownload(appName);
emit updateDisplay(); // 触发重绘
return true;
}
}
qDebug() << "点击了第" << index.row() << "";
return true;
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}

View File

@ -3,8 +3,10 @@
#include <QStyledItemDelegate>
#include <QPainter>
// 添加 QEvent 头文件
#include <QEvent>
#include <QMouseEvent>
// 前向声明 DownloadManager 类
class DownloadManager;
class AppDelegate : public QStyledItemDelegate
{
@ -16,6 +18,14 @@ public:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;
signals:
void updateDisplay(); // 声明更新显示的信号
private:
DownloadManager *m_downloadManager; // 声明下载管理器指针
int m_progress = 0; // 声明下载进度
bool m_isDownloading = false; // 声明下载状态
};
#endif // APPDELEGATE_H

53
src/downloadmanager.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "downloadmanager.h"
DownloadManager::DownloadManager(QObject *parent) : QObject(parent), m_process(new QProcess(this))
{
m_progressRegex = QRegularExpression(R"(\((\d+)%\))");
connect(m_process, &QProcess::readyReadStandardOutput, this, &DownloadManager::onProcessReadyRead);
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &DownloadManager::onProcessFinished);
}
DownloadManager::~DownloadManager()
{
if (m_process->state() == QProcess::Running) {
m_process->kill();
m_process->waitForFinished();
}
}
void DownloadManager::startDownload(const QString &appName)
{
QString command = QString("aptss download --print-uris %1").arg(appName);
m_process->start(command);
}
void DownloadManager::onProcessReadyRead()
{
QByteArray output = m_process->readAllStandardOutput();
QString outputStr = QString::fromUtf8(output);
QRegularExpressionMatch match = m_progressRegex.match(outputStr);
if (match.hasMatch()) {
int progress = match.captured(1).toInt();
emit downloadProgress(progress);
}
}
void DownloadManager::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
bool success = (exitStatus == QProcess::NormalExit && exitCode == 0);
emit downloadFinished(success);
}
bool DownloadManager::isRunning() const
{
return m_process->state() == QProcess::Running;
}
void DownloadManager::killProcess()
{
if (m_process->state() == QProcess::Running) {
m_process->kill();
m_process->waitForFinished();
}
}

32
src/downloadmanager.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
#include <QObject>
#include <QProcess>
#include <QRegularExpression>
class DownloadManager : public QObject
{
Q_OBJECT
public:
explicit DownloadManager(QObject *parent = nullptr);
~DownloadManager();
void startDownload(const QString &appName);
bool isRunning() const; // 声明 isRunning 方法
void killProcess(); // 声明 killProcess 方法
signals:
void downloadProgress(int progress);
void downloadFinished(bool success);
private slots:
void onProcessReadyRead();
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
QProcess *m_process;
QRegularExpression m_progressRegex;
};
#endif // DOWNLOADMANAGER_H