Barra de progrés per a la comprovació d'actualitzacions

- CheckUpdatesWorker emet progress(done, total) per cada joc intentat (èxit o
  error), amb total = jocs descarregats; així la barra arriba al final encara
  que algun repo doni timeout.
- QProgressBar a la status bar (amagada per defecte) que es mostra durant la
  comprovació i s'amaga en acabar o en error. Reutilitzada pel check manual i
  l'automàtic a l'inici.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 09:03:58 +02:00
parent c51b7b74ed
commit e9f0098df8
2 changed files with 30 additions and 5 deletions
+19
View File
@@ -12,6 +12,7 @@ from PySide6.QtWidgets import (
QMainWindow,
QMessageBox,
QPlainTextEdit,
QProgressBar,
QScrollArea,
QSplitter,
QVBoxLayout,
@@ -78,6 +79,14 @@ class MainWindow(QMainWindow):
self.setCentralWidget(splitter)
# Barra de progrés (cantonada de la status bar) per a la comprovació d'updates;
# amagada fins que arrenca una comprovació.
self.progress = QProgressBar()
self.progress.setMaximumWidth(220)
self.progress.setFormat("Comprovant %v/%m")
self.progress.hide()
self.statusBar().addPermanentWidget(self.progress)
# Estado persistido: marcas de update + filtro de ocultar no descargados.
for game_id in self.settings.updates_pending:
if game_id in self.rows:
@@ -171,11 +180,19 @@ class MainWindow(QMainWindow):
)
worker.signals.log.connect(self._log)
worker.signals.result.connect(self._mark_update)
worker.signals.progress.connect(self._check_progress)
worker.signals.finished.connect(self._check_done)
worker.signals.error.connect(self._check_error)
self._track(worker)
self.pool.start(worker)
def _check_progress(self, done: int, total: int) -> None:
if total <= 0:
return # res descarregat a comprovar: no mostrem barra
self.progress.setMaximum(total)
self.progress.setValue(done)
self.progress.show()
def _mark_update(self, game_id: str, has_update: bool) -> None:
row = self.rows.get(game_id)
if row is not None:
@@ -187,10 +204,12 @@ class MainWindow(QMainWindow):
def _check_done(self, _payload) -> None:
self.action_check.setEnabled(True)
self.progress.hide()
self._log("=== Comprovació d'actualitzacions acabada ===")
def _check_error(self, msg: str) -> None:
self.action_check.setEnabled(True)
self.progress.hide()
self._log(f"!!! Error comprovant actualitzacions: {msg}")
# --------------------------------------------------------------- helpers
+11 -5
View File
@@ -20,6 +20,7 @@ class _Signals(QObject):
finished = Signal(object) # payload según el worker (GameMeta o int exit code)
error = Signal(str) # mensaje de error
result = Signal(str, bool) # (game_id, has_update) — CheckUpdatesWorker
progress = Signal(int, int) # (done, total) — CheckUpdatesWorker
class DownloadWorker(QRunnable):
@@ -94,9 +95,13 @@ class CheckUpdatesWorker(QRunnable):
def run(self) -> None: # noqa: D401 - API de QRunnable
try:
for game in self.games:
if not gitops.is_installed(self.root, game):
continue
# Total = juegos descargados (los no instalados no se comprueban). Emitimos
# progress por cada juego *intentado*, éxito o error, para que la barra
# llegue siempre al final aunque algún repo dé timeout.
installed = [g for g in self.games if gitops.is_installed(self.root, g)]
total = len(installed)
self.signals.progress.emit(0, total)
for done, game in enumerate(installed, start=1):
try:
has_update = gitops.check_update(
self.root,
@@ -107,8 +112,9 @@ class CheckUpdatesWorker(QRunnable):
)
except Exception as exc: # noqa: BLE001 - no abortar el resto
self.signals.log.emit(f"check {game.id}: {exc}")
continue
self.signals.result.emit(game.id, has_update)
else:
self.signals.result.emit(game.id, has_update)
self.signals.progress.emit(done, total)
except Exception as exc: # noqa: BLE001 - reportar a la UI
self.signals.error.emit(str(exc))
return