feat: sample camera starts in scale-to-fit
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / test (3.11) (pull_request) Successful in 1m8s
CI / test (3.12) (pull_request) Successful in 1m11s
CI / test (3.13) (pull_request) Successful in 1m9s
CI / lint (pull_request) Canceled after 1m20s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Canceled after 1m10s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Canceled after 1m7s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Canceled after 1m5s
CI / test-with-coverage (pull_request) Canceled after 1m2s
CI / coverage-analysis (pull_request) Canceled after 0s

_autoscale now defaults on, so the view fits from the first layout
(the constructor's placeholder already carries the camera size and
resizeEvent refits on every resize). update_pixmap additionally
refits when the frame size changes - the real stream resolution can
differ from the placeholder, and only a view resize refit before.
Right-click 'Scale to fit' still toggles back to 1:1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 16:49:30 +02:00
co-authored by Claude Fable 5
parent 6ace1fcbcf
commit b58c23d0f6
2 changed files with 25 additions and 1 deletions
+9 -1
View File
@@ -133,7 +133,9 @@ class SampleCameraImageLabel(QGraphicsView):
self._geom = geom
self._bookmarks: SmargonBookmarkList = SmargonBookmarkList()
self._autoscale = False
# Fit-to-view from the first frame; the right-click "Scale to fit"
# toggle can still switch back to 1:1.
self._autoscale = True
self._show_coords = False
self._helical_start = SmargonCoordinate()
self._helical_end = SmargonCoordinate()
@@ -776,12 +778,18 @@ class SampleCameraImageLabel(QGraphicsView):
@Slot(QPixmap)
def update_pixmap(self, pixmap: QPixmap):
size_changed = self.pixmap_item is None or self.pixmap_item.pixmap().size() != pixmap.size()
if self.pixmap_item is not None: # Ensure pixmap_item exists
self.pixmap_item.setPixmap(pixmap) # Update the pixmap in the item
else:
# If no pixmap item exists (rare case), create one
self.pixmap_item = QGraphicsPixmapItem(pixmap)
self.scene.addItem(self.pixmap_item)
if size_changed and self._autoscale:
# Refit when the frame size differs from what was fitted (real
# stream resolution vs the 2000x2000 startup placeholder, or a
# camera source switch) — resizeEvent only refits on view resize.
self._scaling()
self.viewport().update() # Request an update to redraw the view
@Slot(DAQStatusModel)
+16
View File
@@ -209,3 +209,19 @@ def test_alt_wheel_axis_swap_still_changes_exposure(camera):
n = len(sent)
camera.wheelEvent(_wheel(camera)) # zero delta: ignored
assert len(sent) == n
def test_autoscale_fits_from_the_first_frame(camera):
from PySide6.QtGui import QPixmap
# Fit-to-view is the default; a frame whose size differs from the fitted
# one (here: the 2000x2000 startup placeholder) must refit immediately,
# not wait for the next view resize.
assert camera._autoscale
camera.update_pixmap(QPixmap(4000, 4000))
assert camera.transform().m11() < 1.0
# The right-click toggle still restores 1:1.
camera._autoscale = False
camera._scaling()
assert camera.transform().isIdentity()