Fix sweep/scan Stop button and state cleanup
_sweeping/_scanning flags were never reset when workers finished, leaving the UI stuck in "Stopping..." forever. Both _do_sweep and _do_scan now use try/finally to always clear state and reset button styles. Firmware sweep checks the flag after the blocking serial call returns and discards results if Stop was pressed mid-execution.
This commit is contained in:
parent
3cd6424168
commit
2ee2f47275
@ -434,6 +434,7 @@ class SignalScreen(Container):
|
|||||||
if device is None:
|
if device is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
# Check if user forced software mode.
|
# Check if user forced software mode.
|
||||||
force_software = self.query_one("#sweep-software-mode", Checkbox).value
|
force_software = self.query_one("#sweep-software-mode", Checkbox).value
|
||||||
|
|
||||||
@ -447,10 +448,14 @@ class SignalScreen(Container):
|
|||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
self.app.call_from_thread(
|
self.app.call_from_thread(
|
||||||
self._set_sweep_status, "Firmware sweep failed -- falling back..."
|
self._set_sweep_status,
|
||||||
|
"Firmware sweep failed -- falling back...",
|
||||||
)
|
)
|
||||||
|
|
||||||
self._do_sweep_software(device)
|
self._do_sweep_software(device)
|
||||||
|
finally:
|
||||||
|
self._sweeping = False
|
||||||
|
self.app.call_from_thread(self._reset_sweep_buttons)
|
||||||
|
|
||||||
def _do_sweep_firmware(self, device: DeviceLike) -> None:
|
def _do_sweep_firmware(self, device: DeviceLike) -> None:
|
||||||
"""Firmware-accelerated sweep via azscanwxp (runs in worker thread)."""
|
"""Firmware-accelerated sweep via azscanwxp (runs in worker thread)."""
|
||||||
@ -494,6 +499,11 @@ class SignalScreen(Container):
|
|||||||
num_xponders=iterations,
|
num_xponders=iterations,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check if Stop was pressed while firmware was executing.
|
||||||
|
if not self._sweeping or shutdown.is_set():
|
||||||
|
self.app.call_from_thread(self._set_sweep_status, "Sweep stopped")
|
||||||
|
return
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
self.app.call_from_thread(
|
self.app.call_from_thread(
|
||||||
self._set_sweep_status, "Firmware sweep returned no data"
|
self._set_sweep_status, "Firmware sweep returned no data"
|
||||||
@ -600,6 +610,11 @@ class SignalScreen(Container):
|
|||||||
self.query_one("#sweep-progress", ProgressBar).update(progress=pct)
|
self.query_one("#sweep-progress", ProgressBar).update(progress=pct)
|
||||||
self.query_one("#sweep-status-text", Static).update(status_text)
|
self.query_one("#sweep-status-text", Static).update(status_text)
|
||||||
|
|
||||||
|
def _reset_sweep_buttons(self) -> None:
|
||||||
|
"""Restore sweep button styles to idle state (main thread)."""
|
||||||
|
self.query_one("#btn-start-sweep", Button).variant = "primary"
|
||||||
|
self.query_one("#btn-stop-sweep", Button).variant = "default"
|
||||||
|
|
||||||
# -- Sweep button handlers --
|
# -- Sweep button handlers --
|
||||||
|
|
||||||
def _handle_sweep_start(self) -> None:
|
def _handle_sweep_start(self) -> None:
|
||||||
@ -616,12 +631,16 @@ class SignalScreen(Container):
|
|||||||
self.query_one("#sweep-progress", ProgressBar).update(progress=0)
|
self.query_one("#sweep-progress", ProgressBar).update(progress=0)
|
||||||
self._set_sweep_status("Starting sweep...")
|
self._set_sweep_status("Starting sweep...")
|
||||||
|
|
||||||
|
self.query_one("#btn-start-sweep", Button).variant = "default"
|
||||||
|
self.query_one("#btn-stop-sweep", Button).variant = "warning"
|
||||||
|
|
||||||
self._sweeping = True
|
self._sweeping = True
|
||||||
self._do_sweep()
|
self._do_sweep()
|
||||||
|
|
||||||
def _handle_sweep_stop(self) -> None:
|
def _handle_sweep_stop(self) -> None:
|
||||||
self._sweeping = False
|
self._sweeping = False
|
||||||
self._set_sweep_status("Stopping...")
|
self._set_sweep_status("Stopping...")
|
||||||
|
self._reset_sweep_buttons()
|
||||||
|
|
||||||
def _export_sweep_csv(self) -> None:
|
def _export_sweep_csv(self) -> None:
|
||||||
if not self._sweep_data:
|
if not self._sweep_data:
|
||||||
@ -647,12 +666,21 @@ class SignalScreen(Container):
|
|||||||
@work(thread=True)
|
@work(thread=True)
|
||||||
def _do_scan(self) -> None:
|
def _do_scan(self) -> None:
|
||||||
"""Execute the AZ/EL grid scan in a background thread."""
|
"""Execute the AZ/EL grid scan in a background thread."""
|
||||||
worker = get_current_worker()
|
|
||||||
shutdown = self.app.shutdown_event
|
|
||||||
device = self._device
|
device = self._device
|
||||||
if device is None:
|
if device is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._do_scan_inner(device)
|
||||||
|
finally:
|
||||||
|
self._scanning = False
|
||||||
|
self.app.call_from_thread(self._reset_scan_buttons)
|
||||||
|
|
||||||
|
def _do_scan_inner(self, device: DeviceLike) -> None:
|
||||||
|
"""Inner scan logic (called from _do_scan worker thread)."""
|
||||||
|
worker = get_current_worker()
|
||||||
|
shutdown = self.app.shutdown_event
|
||||||
|
|
||||||
az_start = self._read_float("scan-az-start", 160.0)
|
az_start = self._read_float("scan-az-start", 160.0)
|
||||||
az_end = self._read_float("scan-az-end", 220.0)
|
az_end = self._read_float("scan-az-end", 220.0)
|
||||||
az_step = self._read_float("scan-az-step", 1.5)
|
az_step = self._read_float("scan-az-step", 1.5)
|
||||||
@ -815,6 +843,11 @@ class SignalScreen(Container):
|
|||||||
self.query_one("#scan-progress", ProgressBar).update(progress=pct)
|
self.query_one("#scan-progress", ProgressBar).update(progress=pct)
|
||||||
self.query_one("#scan-status-text", Static).update(status_text)
|
self.query_one("#scan-status-text", Static).update(status_text)
|
||||||
|
|
||||||
|
def _reset_scan_buttons(self) -> None:
|
||||||
|
"""Restore scan button styles to idle state (main thread)."""
|
||||||
|
self.query_one("#btn-start-scan", Button).variant = "primary"
|
||||||
|
self.query_one("#btn-stop-scan", Button).variant = "default"
|
||||||
|
|
||||||
# -- Scan button handlers --
|
# -- Scan button handlers --
|
||||||
|
|
||||||
def _handle_scan_start(self) -> None:
|
def _handle_scan_start(self) -> None:
|
||||||
@ -831,12 +864,16 @@ class SignalScreen(Container):
|
|||||||
self.query_one("#scan-progress", ProgressBar).update(progress=0)
|
self.query_one("#scan-progress", ProgressBar).update(progress=0)
|
||||||
self._set_scan_status("Starting scan...")
|
self._set_scan_status("Starting scan...")
|
||||||
|
|
||||||
|
self.query_one("#btn-start-scan", Button).variant = "default"
|
||||||
|
self.query_one("#btn-stop-scan", Button).variant = "warning"
|
||||||
|
|
||||||
self._scanning = True
|
self._scanning = True
|
||||||
self._do_scan()
|
self._do_scan()
|
||||||
|
|
||||||
def _handle_scan_stop(self) -> None:
|
def _handle_scan_stop(self) -> None:
|
||||||
self._scanning = False
|
self._scanning = False
|
||||||
self._set_scan_status("Stopping...")
|
self._set_scan_status("Stopping...")
|
||||||
|
self._reset_scan_buttons()
|
||||||
|
|
||||||
def _export_scan_csv(self) -> None:
|
def _export_scan_csv(self) -> None:
|
||||||
if not self._scan_data:
|
if not self._scan_data:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user