From 11f898c1b8a3aa1a5dbf8c38fb7b1b519723726d Mon Sep 17 00:00:00 2001 From: Hongquan Li Date: Fri, 16 Jan 2026 13:39:39 -0800 Subject: [PATCH 1/2] Fix pytest compatibility with root __init__.py shim The root __init__.py is a shim for Squid submodule usage that uses relative imports. When pytest tries to import it directly (not as a submodule), the relative imports fail. Fix by wrapping imports in `if __package__:` so they only execute when used as an actual submodule. Also add explicit pytest config. Co-Authored-By: Claude Opus 4.5 --- __init__.py | 58 ++++++++++++++++++++++++++------------------------ pyproject.toml | 6 ++++++ 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/__init__.py b/__init__.py index cb259db..941c932 100644 --- a/__init__.py +++ b/__init__.py @@ -1,31 +1,33 @@ # Shim for submodule usage in Squid # Re-exports from the nested ndviewer_light package -from .ndviewer_light import ( - __version__, - FPATTERN, - FPATTERN_OME, - MAX_3D_TEXTURE_SIZE, - LightweightMainWindow, - LightweightViewer, - data_structure_changed, - detect_format, - extract_ome_physical_sizes, - read_acquisition_parameters, - read_tiff_pixel_size, - wavelength_to_colormap, -) +# Only imports when used as a submodule (has parent package) +if __package__: + from .ndviewer_light import ( + __version__, + FPATTERN, + FPATTERN_OME, + MAX_3D_TEXTURE_SIZE, + LightweightMainWindow, + LightweightViewer, + data_structure_changed, + detect_format, + extract_ome_physical_sizes, + read_acquisition_parameters, + read_tiff_pixel_size, + wavelength_to_colormap, + ) -__all__ = [ - "__version__", - "FPATTERN", - "FPATTERN_OME", - "MAX_3D_TEXTURE_SIZE", - "LightweightMainWindow", - "LightweightViewer", - "data_structure_changed", - "detect_format", - "extract_ome_physical_sizes", - "read_acquisition_parameters", - "read_tiff_pixel_size", - "wavelength_to_colormap", -] + __all__ = [ + "__version__", + "FPATTERN", + "FPATTERN_OME", + "MAX_3D_TEXTURE_SIZE", + "LightweightMainWindow", + "LightweightViewer", + "data_structure_changed", + "detect_format", + "extract_ome_physical_sizes", + "read_acquisition_parameters", + "read_tiff_pixel_size", + "wavelength_to_colormap", + ] diff --git a/pyproject.toml b/pyproject.toml index ac5e657..6e88bf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,3 +24,9 @@ dependencies = [ [tool.setuptools.packages.find] where = ["."] include = ["ndviewer_light"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] +norecursedirs = ["__pycache__"] +addopts = "--ignore=__init__.py" From dc0aeabaf38ed075a66dd431efc1ebe70f0fb5cc Mon Sep 17 00:00:00 2001 From: Hongquan Li Date: Fri, 16 Jan 2026 13:39:45 -0800 Subject: [PATCH 2/2] Add proportional slider handle sizing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make slider handle width proportional to the number of positions: - Few positions (e.g., 3 channels) → wider handle (up to 40px) - Many positions (e.g., 100 timepoints) → narrower handle (min 8px) This provides better visual feedback about the slider's range. Implementation extends the existing QLabeledSlider.setRange() monkey patch to apply dynamic stylesheets based on the range size. Co-Authored-By: Claude Opus 4.5 --- ndviewer_light/core.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ndviewer_light/core.py b/ndviewer_light/core.py index aad2e05..0bb076e 100644 --- a/ndviewer_light/core.py +++ b/ndviewer_light/core.py @@ -57,6 +57,17 @@ def _patched_setRange(self, a, b): if hasattr(self, "_slider"): self._slider.setMinimum(a) self._slider.setMaximum(b) + + # Proportional handle sizing based on number of positions + num_positions = b - a + 1 + # Scale handle: larger for fewer positions, smaller for many + # Clamp between 8px (minimum usable) and 40px (maximum reasonable) + handle_width = max(8, min(40, 200 // max(1, num_positions))) + self._slider.setStyleSheet( + f"QSlider::handle:horizontal {{ width: {handle_width}px; }}" + f"QSlider::handle:vertical {{ height: {handle_width}px; }}" + ) + if hasattr(self, "_label"): try: self._label.setRange(a, b)