feat:添加复选框让用户选择指定软件更新

This commit is contained in:
2025-09-28 15:22:24 +08:00
parent 975e3f6afb
commit b461729fa5
4 changed files with 104 additions and 4 deletions

View File

@@ -51,6 +51,24 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
else
painter->fillRect(option.rect, QColor("#F3F4F6"));
// 绘制复选框
QString packageName = index.data(Qt::UserRole + 1).toString();
bool isSelected = m_selectedPackages.contains(packageName);
QRect checkboxRect(option.rect.left() + 10, option.rect.top() + (option.rect.height() - 20) / 2, 20, 20);
// 绘制复选框边框
painter->setPen(QColor("#888888"));
painter->setBrush(Qt::NoBrush);
painter->drawRect(checkboxRect);
// 如果选中,绘制勾选标记
if (isSelected) {
painter->setPen(QPen(QColor("#2563EB"), 2));
painter->setBrush(QColor("#2563EB"));
painter->drawRect(checkboxRect.adjusted(4, 4, -4, -4));
}
QFont boldFont = option.font;
boldFont.setBold(true);
QFont normalFont = option.font;
@@ -65,7 +83,8 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
QRect rect = option.rect;
int margin = 10, spacing = 6, iconSize = 40;
QRect iconRect(rect.left() + margin, rect.top() + (rect.height() - iconSize) / 2, iconSize, iconSize);
// 调整图标位置,为复选框留出空间
QRect iconRect(rect.left() + 40, rect.top() + (rect.height() - iconSize) / 2, iconSize, iconSize);
QIcon(iconPath).paint(painter, iconRect);
int textX = iconRect.right() + margin;
@@ -88,7 +107,6 @@ void AppDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, c
painter->drawText(descRect, Qt::TextWordWrap,
QString("包大小:%1 MB").arg(QString::number(size.toDouble() / (1024 * 1024), 'f', 2)));
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;
bool isInstalled = m_downloads.value(packageName).isInstalled;
@@ -162,6 +180,18 @@ bool AppDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
QRect rect = option.rect;
QString packageName = index.data(Qt::UserRole + 1).toString();
// 检查是否点击了复选框
QRect checkboxRect(rect.left() + 10, rect.top() + (rect.height() - 20) / 2, 20, 20);
if (checkboxRect.contains(mouseEvent->pos())) {
if (m_selectedPackages.contains(packageName)) {
m_selectedPackages.remove(packageName);
} else {
m_selectedPackages.insert(packageName);
}
emit updateDisplay(packageName);
return true;
}
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())) {
@@ -320,4 +350,37 @@ void AppDelegate::startNextInstall() {
void AppDelegate::updateSpinner() {
m_spinnerAngle = (m_spinnerAngle + 10) % 360; // 每次增加10度
emit updateDisplay(m_installingPackage); // 仅刷新当前正在安装的项
}
// 新增:更新选中应用的方法
void AppDelegate::startDownloadForSelected() {
if (!m_model) return;
for (int row = 0; row < m_model->rowCount(); ++row) {
QModelIndex index = m_model->index(row, 0);
QString packageName = index.data(Qt::UserRole + 1).toString();
// 只下载选中的应用
if (m_selectedPackages.contains(packageName)) {
if (m_downloads.contains(packageName) && (m_downloads[packageName].isDownloading || m_downloads[packageName].isInstalled))
continue;
QString downloadUrl = index.data(Qt::UserRole + 7).toString();
QString outputPath = QString("%1/%2.metalink").arg(QDir::tempPath(), packageName);
m_downloads[packageName] = {0, true, false};
m_downloadManager->startDownload(packageName, downloadUrl, outputPath);
emit updateDisplay(packageName);
}
}
}
// 复选框相关方法实现
void AppDelegate::setSelectedPackages(const QSet<QString> &selected) {
m_selectedPackages = selected;
}
QSet<QString> AppDelegate::getSelectedPackages() const {
return m_selectedPackages;
}
void AppDelegate::clearSelection() {
m_selectedPackages.clear();
}

View File

@@ -28,6 +28,12 @@ public:
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index) override;
void startDownloadForAll();
void startDownloadForSelected();
// 复选框相关方法
void setSelectedPackages(const QSet<QString> &selected);
QSet<QString> getSelectedPackages() const;
void clearSelection();
signals:
void updateDisplay(const QString &packageName);
@@ -40,6 +46,9 @@ private:
DownloadManager *m_downloadManager;
QHash<QString, DownloadInfo> m_downloads;
QAbstractItemModel *m_model = nullptr;
// 复选框相关成员变量
QSet<QString> m_selectedPackages;
QQueue<QString> m_installQueue;
bool m_isInstalling = false;

View File

@@ -55,9 +55,20 @@ MainWindow::MainWindow(QWidget *parent)
// 新增:点击“更新全部”按钮批量下载
connect(ui->updatePushButton, &QPushButton::clicked, this, [=](){
qDebug()<<"更新全部按钮被点击";
m_delegate->startDownloadForAll();
qDebug()<<"更新按钮被点击";
if (m_delegate->getSelectedPackages().isEmpty()) {
// 没有选中任何应用,更新全部
m_delegate->startDownloadForAll();
} else {
// 有选中应用,更新选中
m_delegate->startDownloadForSelected();
m_delegate->clearSelection();
updateButtonText();
}
});
// 新增:监听选择变化
connect(m_delegate, &AppDelegate::updateDisplay, this, &MainWindow::handleSelectionChanged);
checkUpdates();
// 新增:监听搜索框文本变化
@@ -283,4 +294,19 @@ void MainWindow::handleUpdateFinished(bool success)
MainWindow::~MainWindow()
{
delete ui;
}
// 新增:更新按钮文本
void MainWindow::updateButtonText() {
int selectedCount = m_delegate->getSelectedPackages().size();
if (selectedCount > 0) {
ui->updatePushButton->setText(QString("更新选中(%1)").arg(selectedCount));
} else {
ui->updatePushButton->setText("更新全部");
}
}
// 新增:处理选择变化
void MainWindow::handleSelectionChanged() {
updateButtonText();
}

View File

@@ -35,8 +35,10 @@ private:
QListView *listView; // 声明 QListView 指针
QJsonArray m_allApps; // 新增:保存所有应用数据
void filterAppsByKeyword(const QString &keyword); // 新增:搜索过滤函数声明
void updateButtonText(); // 新增:更新按钮文本
private slots:
void handleUpdateFinished(bool success); // 新增:处理更新完成的槽函数
void handleSelectionChanged(); // 新增:处理选择变化的槽函数
};
#endif // MAINWINDOW_H