diff --git a/src/pymmcore_widgets/useq_widgets/_grid.py b/src/pymmcore_widgets/useq_widgets/_grid.py index ab8ed6b80..6d1af41bf 100644 --- a/src/pymmcore_widgets/useq_widgets/_grid.py +++ b/src/pymmcore_widgets/useq_widgets/_grid.py @@ -4,7 +4,7 @@ from typing import Literal, Sequence, cast import useq -from qtpy.QtCore import Qt, Signal +from qtpy.QtCore import QSize, Qt, Signal from qtpy.QtGui import QPainter, QPaintEvent, QPen from qtpy.QtWidgets import ( QAbstractButton, @@ -15,6 +15,7 @@ QHBoxLayout, QLabel, QRadioButton, + QScrollArea, QSpinBox, QVBoxLayout, QWidget, @@ -44,7 +45,7 @@ class Mode(Enum): BOUNDS = "bounds" -class GridPlanWidget(QWidget): +class GridPlanWidget(QScrollArea): """Widget to edit a [`useq-schema` GridPlan](https://pymmcore-plus.github.io/useq-schema/schema/axes/#grid-plans).""" valueChanged = Signal(object) @@ -161,7 +162,9 @@ def __init__(self, parent: QWidget | None = None): bottom_stuff.addLayout(bot_left) - layout = QVBoxLayout(self) + # wrap the whole thing in an inner widget so we can put it in this ScrollArea + inner_widget = QWidget(self) + layout = QVBoxLayout(inner_widget) layout.addLayout(row_col_layout) layout.addWidget(_SeparatorWidget()) layout.addLayout(width_height_layout) # hiding until useq supports it @@ -171,6 +174,11 @@ def __init__(self, parent: QWidget | None = None): layout.addLayout(bottom_stuff) layout.addStretch() + self.setWidget(inner_widget) + self.setWidgetResizable(True) + self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) + self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) + self.mode_groups: dict[Mode, Sequence[QWidget]] = { Mode.NUMBER: (self.rows, self.columns), Mode.AREA: (self.area_width, self.area_height), @@ -343,6 +351,12 @@ def fovHeight(self) -> float | None: # ------------------------- Private API ------------------------- + def sizeHint(self) -> QSize: + """Return the size hint for the viewport.""" + sz = super().sizeHint() + sz.setHeight(200) # encourage vertical scrolling + return sz + def _on_change(self) -> None: if (val := self.value()) is None: return # pragma: no cover