Skip to content

fix: AttributeError when selecting Simple Recording/Tracking tab - #584

Merged
hongquanli merged 2 commits into
masterfrom
fix/ontabchanged-nonacquisition-tabs
Jul 6, 2026
Merged

fix: AttributeError when selecting Simple Recording/Tracking tab#584
hongquanli merged 2 commits into
masterfrom
fix/ontabchanged-nonacquisition-tabs

Conversation

@hongquanli

@hongquanli hongquanli commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Selecting the Simple Recording tab (or Tracking tab) crashes with:

File "control/gui_hcs.py", line 2360, in onTabChanged
    acquisitionWidget.emit_selected_channels()
AttributeError: 'RecordingWidget' object has no attribute 'emit_selected_channels'

onTabChanged called emit_selected_channels() on whatever record tab was selected, but only the multipoint widgets (Flexible, Wellplate, Fluidics) define that method. Most machine configs have ENABLE_RECORDING off, which is why this went unnoticed. toggleAcquisitionStart had the same latent bug with display_progress_bar().

Fix (structural, no hasattr guards)

The first commit guarded both calls with hasattr; the second commit replaces that with a structural fix:

Channels: emit at acquisition start, not tab change. The napari multichannel viewer needs two inputs: shape and channels. Shape was already emitted at acquisition start (next to signal_acquisition_started); channels rode on tab change. Now emit_selected_channels() is called at the same acquisition-start point in all three multipoint widgets — Wellplate's _set_ui_acquisition_running covers both the button path and the TCP/invokeMethod path. onTabChanged no longer calls anything on the selected tab, so tabs without channel selections are never asked. Timing is safe: the only consumer of the channel set (updateLayers) runs exclusively during an acquisition, and the per-tab itemSelectionChanged connections still keep it fresh in between.

Progress bar: delete the gui_hcs call. Every widget with a progress bar already connects its own signal_acquisition_started to its own display_progress_bar, and toggleAcquisitionStart is only ever invoked via that same signal — the call in gui_hcs was redundant for multipoint tabs and a crash for the rest.

Testing

  • Regression test: builds the simulated GUI with ENABLE_RECORDING patched on, switches to the Simple Recording tab, and cycles toggleAcquisitionStart — reproduced the exact AttributeError before the fix, passes after.
  • New test: signal_acquisition_channels is emitted at acquisition start with the selected channel names.
  • All 4 tests in tests/control/test_HighContentScreeningGui.py pass locally with QT_API=pyqt5 (this file is skipped in CI).
  • black clean.

🤖 Generated with Claude Code

hongquanli and others added 2 commits July 5, 2026 20:34
… tabs

onTabChanged unconditionally called emit_selected_channels() on whatever
record tab was selected, but only the multipoint widgets define it.
Selecting the Simple Recording (or Tracking) tab raised AttributeError
on machines with ENABLE_RECORDING/ENABLE_TRACKING on.

toggleAcquisitionStart had the same latent issue with
display_progress_bar() when a workflow/TCP acquisition starts while a
non-multipoint tab is current.

Guard both with hasattr, matching the existing pattern in
_run_acquisition_for_workflow, and add a regression test that builds
the simulated GUI with ENABLE_RECORDING on and exercises both paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…change

Replace the hasattr guards with a structural fix:

- The napari multichannel viewer's channel set is now initialized where
  its shape already is: at acquisition start, next to
  signal_acquisition_shape, in all three multipoint widgets (Wellplate's
  _set_ui_acquisition_running covers both the button and TCP paths).
  onTabChanged no longer calls anything on the selected tab, so
  non-multipoint tabs (Simple Recording, Tracking) are never asked for
  channel selections they don't have.

- Drop the display_progress_bar call from toggleAcquisitionStart
  entirely: every widget with a progress bar already connects its own
  signal_acquisition_started to display_progress_bar, so the call was
  redundant for multipoint tabs and a crash for the rest.

Add a test that signal_acquisition_channels is emitted at acquisition
start with the selected channel names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hongquanli
hongquanli merged commit 780d80e into master Jul 6, 2026
3 checks passed
hongquanli added a commit that referenced this pull request Jul 6, 2026
)

master (PR #584) removed the duck-typed emit_selected_channels() /
display_progress_bar() calls from gui_hcs.onTabChanged and
toggleAcquisitionStart — channels are now emitted by each multipoint
widget at acquisition start. RecordZStackMultiPointWidget's no-op stubs
(added in 9b5be65 to satisfy the old contract) and their regression
test are now unreachable dead code; remove them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Alpaca233 pushed a commit that referenced this pull request Jul 27, 2026
)

master (PR #584) removed the duck-typed emit_selected_channels() /
display_progress_bar() calls from gui_hcs.onTabChanged and
toggleAcquisitionStart — channels are now emitted by each multipoint
widget at acquisition start. RecordZStackMultiPointWidget's no-op stubs
(added in 9b5be65 to satisfy the old contract) and their regression
test are now unreachable dead code; remove them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant