收起复用与完成态分析横幅。

来源栏已显示结果状态,横幅约 1.5 秒后只隐藏控件并保留 state()。已用 apps/studio/tests/test_analysis_progress.py 验证。
This commit is contained in:
ykcheungab
2026-10-07 09:37:08 +08:00
parent 97e80d3d38
commit 6194778a6f
2 changed files with 79 additions and 2 deletions
@@ -28,7 +28,7 @@ from __future__ import annotations
from orisys_app_shared.i18n import t
from orisys_app_shared.theme import color
from PySide6.QtCore import Qt, Signal
from PySide6.QtCore import Qt, QTimer, Signal
from PySide6.QtWidgets import (
QFrame,
QHBoxLayout,
@@ -71,6 +71,10 @@ _STATE_TITLE = {
#: The progress bar's thousandths (Qt's own percentage unit, 0–1000).
_FULL = 1000
#: How long a reused / complete banner stays on screen before collapsing. The rail
#: already names the result state, so the banner must not keep stealing height.
_COLLAPSE_MS = 1500
class AnalysisProgress(QFrame):
"""Shows one analysis pass: how far, which segment, and how to stop it."""
@@ -104,6 +108,9 @@ class AnalysisProgress(QFrame):
self.cancel_button.setObjectName("analysisCancel")
self.cancel_button.setToolTip(t("analysis.cancel_tip"))
self.cancel_button.clicked.connect(self._on_cancel_clicked)
self._collapse_timer = QTimer(self)
self._collapse_timer.setSingleShot(True)
self._collapse_timer.timeout.connect(self._collapse_success_banner)
footer = QHBoxLayout()
footer.setContentsMargins(0, 0, 0, 0)
@@ -135,6 +142,7 @@ class AnalysisProgress(QFrame):
def start(self) -> None:
"""A pass began: show the surface empty and cancellable."""
self._cancel_collapse()
self._state = RUNNING
self._cancelling = False
self._detail = ""
@@ -186,6 +194,7 @@ class AnalysisProgress(QFrame):
self._detail = ""
self.setVisible(True)
self._refresh()
self._schedule_collapse()
def complete(self, *, frames: int = 0, elapsed_s: float = 0.0) -> None:
"""The pass finished and the result may be played from."""
@@ -196,9 +205,11 @@ class AnalysisProgress(QFrame):
self._detail = t("analysis.complete", frames=int(frames), seconds=float(elapsed_s))
self.setVisible(True)
self._refresh()
self._schedule_collapse()
def cancelled(self, *, frames: int = 0) -> None:
"""The pass was stopped: the result is incomplete and will not be played."""
self._cancel_collapse()
self._state = CANCELLED
self._cancelling = False
self.progress_bar.setValue(0)
@@ -212,6 +223,7 @@ class AnalysisProgress(QFrame):
if cancelled:
self.cancelled(frames=frames)
return
self._cancel_collapse()
self._state = FAILED
self._cancelling = False
self.progress_bar.setValue(0)
@@ -222,6 +234,7 @@ class AnalysisProgress(QFrame):
def clear(self) -> None:
"""Hide the surface: no pass has anything to say."""
self._cancel_collapse()
self._state = IDLE
self._cancelling = False
self._detail = ""
@@ -247,6 +260,19 @@ class AnalysisProgress(QFrame):
self.retranslate()
self.cancel_requested.emit()
def _schedule_collapse(self) -> None:
"""Hide the banner after a short notice; keep ``state()`` for the rail."""
self._collapse_timer.start(_COLLAPSE_MS)
def _cancel_collapse(self) -> None:
if self._collapse_timer.isActive():
self._collapse_timer.stop()
def _collapse_success_banner(self) -> None:
"""Drop only the chrome; reused / complete remain the result's state."""
if self._state in (REUSED, COMPLETE):
self.setVisible(False)
def _refresh(self) -> None:
"""Repaint from the state: colour, title, which chrome is offered, tooltip.