From e9f0098df8ad947fcac27a61a13840d1e6dd1a8d Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 30 May 2026 09:03:58 +0200 Subject: [PATCH] =?UTF-8?q?Barra=20de=20progr=C3=A9s=20per=20a=20la=20comp?= =?UTF-8?q?rovaci=C3=B3=20d'actualitzacions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- jlauncher/ui/main_window.py | 19 +++++++++++++++++++ jlauncher/workers.py | 16 +++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/jlauncher/ui/main_window.py b/jlauncher/ui/main_window.py index e8e7ab9..193fdcf 100644 --- a/jlauncher/ui/main_window.py +++ b/jlauncher/ui/main_window.py @@ -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 diff --git a/jlauncher/workers.py b/jlauncher/workers.py index 8cd3096..2732e7d 100644 --- a/jlauncher/workers.py +++ b/jlauncher/workers.py @@ -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