Skip to content

feat: add Windows setup script and launcher - #642

Merged
Alpaca233 merged 1 commit into
feat/pyqt6-napari07-migration-v2from
feat/windows-setup
Sep 8, 2026
Merged

Alpaca233 merged 1 commit into
feat/pyqt6-napari07-migration-v2from
feat/windows-setup

Conversation

@hongquanli

Copy link
Copy Markdown
Contributor

Stacked on #622. Base is feat/pyqt6-napari07-migration-v2, not master — see Why this can't target master. Retarget once #622 lands.

Problem

There is no reproducible way to install this software on Windows.

What this adds

setup_windows.ps1 — the counterpart of setup_22.04.sh. Installs Git + Python 3.12 via winget, clones recursively, builds a virtualenv with the same pinned PyQt6 6.11 / napari 0.7.1 stack, seeds machine_configs, and writes Desktop shortcuts. Steps with no Windows equivalent are dropped; camera drivers are vendor installers, so the script reports what remains rather than installing it.

main_hcs.bat — the launcher the shortcuts point at.

.gitattributes — two lines pinning *.bat/*.ps1 to eol=crlf. The repo had none, and cmd.exe can misparse a multi-line if errorlevel 1 ( ... ) block in a .bat stored with LF — a failure that presents as a syntax error rather than a line-ending problem.

Deliberate differences from the Ubuntu script

  • A virtualenv, not a system-wide pip install. Windows has no distro Python to protect, and an isolated env is the only way to guarantee exactly one Qt binding — which napari/vispy OpenGL rendering requires.
  • PATH is re-read from the registry after winget. Installers update the registry, not the running process. Without the refresh git.exe is still missing — and control/utils.py imports GitPython at module scope, which raises ImportError with no git executable. That makes git a hard runtime requirement, not just an installer one.
  • It refuses to guess a configuration*.ini. _def.py globs that pattern and silently takes the first match, so the script reports when zero or several are present and lists the candidates. It does seed illumination_channel_config.yaml from the example (its absence degrades the GUI and fails ~13 tests) but warns loudly that the laser lines must be checked.

Why this can't target master

setup_windows.ps1 installs PyQt6 6.11 + napari 0.7.1. On master that produces an environment the code cannot run in — master still sets QT_API = "pyqt5" and uses four APIs that don't exist in PyQt6:

gui_hcs.py:1441:  desktop_info = QDesktopWidget()
gui_hcs.py:2488:  if isinstance(format_, QVariant):
widgets.py:4461:  self.dropdown_modeSelection.activated[str].connect(...)
core.py:1686:     if isinstance(sample_format, QVariant):

These are the exact APIs #622 fixes. They sit inside functions, so the modules import fine and the GUI then fails during construction — and because qtpy falls back from a missing binding with only a warning (Selected binding 'pyqt5' could not be found; falling back to 'pyqt6'), the resulting failure is confusing to diagnose. So this belongs on top of #622.

Verification

On Windows 11 x64, run against an existing checkout to confirm idempotency:

==> Verifying the environment
No broken requirements found.
  qtpy binding : PyQt6
  Qt           : 6.11.0
  napari       : 0.7.1
  numpy        : 2.5.2
  opencv       : 5.0.0

Re-running reuses the venv, leaves an existing illumination_channel_config.yaml alone, detects the single configuration*.ini, and exits 0. main_hcs.bat --simulation brings up the GUI.

Full suite on this branch: 1634 passed, 0 failed, 12 skipped.

Note on scope

This makes Windows a supported platform, which is a policy question as much as a technical one — the README currently says Ubuntu 22.04 is the most tested platform and says nothing about Windows beyond the forum link. Happy to add a README section pointing at this script if you want it discoverable, or to leave it undocumented as a best-effort path.

The repo has no Windows install path. setup_22.04.sh is Ubuntu-only (apt, udev,
dialout, apt-mark), and the forum post the README links for Windows predates the
PyQt6 work -- it installs Python 3.10, PyQt5 and napari 0.5.6. So there was no
reproducible way to stand this software up on Windows.

setup_windows.ps1 is the counterpart of setup_22.04.sh: it installs Git and
Python 3.12 via winget, clones recursively, builds a virtualenv with the same
pinned PyQt6 6.11 / napari 0.7.1 stack, seeds machine_configs, and writes Desktop
shortcuts. Steps with no Windows equivalent (apt, udev rules, dialout, apt-mark)
are dropped; camera drivers are vendor installers rather than bundled .run files,
so the script reports what is still needed instead of installing them.

Three differences from the Ubuntu script are deliberate:

  * A virtualenv, not a system-wide pip install. Windows has no distro Python to
    protect, and an isolated env is the only way to be sure exactly one Qt
    binding is present -- which napari/vispy OpenGL rendering requires.
  * PATH is re-read from the registry after winget runs. The installers update
    the registry, not the running process, so git.exe would otherwise still be
    missing -- and control/utils.py imports GitPython at module scope, which
    raises ImportError without a git executable.
  * The script refuses to guess a configuration*.ini. _def.py globs that pattern
    and silently takes the first match, so it reports when zero or several are
    present and lists the candidates instead.

main_hcs.bat is the launcher the shortcuts point at. It exists so a startup
failure stays readable: a shortcut aimed straight at python.exe closes its
console the instant the process dies, so a bad config or a missing camera driver
would flash past unreadable. It is the counterpart of Terminal=true in the
.desktop entry setup_22.04.sh writes, and doubles as a CLI entry point that
resolves the interpreter and working directory.

Verified on Windows 11 x64: the script runs clean and idempotently against an
existing checkout (pip check reports nothing broken; qtpy resolves to PyQt6 with
Qt 6.11.0, napari 0.7.1, numpy 2.5.2, opencv 5.0.0), and main_hcs.bat --simulation
brings up the GUI.
@Alpaca233
Alpaca233 merged commit 7977471 into feat/pyqt6-napari07-migration-v2 Sep 8, 2026
3 checks passed
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.

2 participants