Repository navigation
Qt6 support: all extra installs napari[qt], fix ROI drawing on PyQt6 - #406
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #406 +/- ##
==========================================
+ Coverage 63.08% 71.66% +8.58%
==========================================
Files 19 19
Lines 2636 3399 +763
==========================================
+ Hits 1663 2436 +773
+ Misses 973 963 -10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
PyQt6 no longer converts QPoint to QPointF implicitly, so ROI drawing in the scatter widget raised TypeError in mapSceneToView / sceneBoundingRect().contains and created no ROI. The handlers now compute the scene position once as self.mapToScene(event.pos()) (a QPointF on every binding) instead of using the viewport position event.pos() as a scene position (same values: pyqtgraph's autoPixelRange keeps scene == viewport pixels). Also fix a log message missing its f-prefix. Tests: pass a QPointF to QMouseEvent, and patch QMessageBox.question via qtpy instead of the PyQt5 module path.
jan-glx
force-pushed
the
jangleixner/qt6
branch
from
November 9, 2026 13:36
ec734a2 to
289a34e
Compare
napari 0.10 requires Qt>=6.7 and no longer has a pyqt5 extra (scverse#405), so napari-spatialdata[all] installed no Qt binding. Pin the binding explicitly to the one napari-spatialdata is tested with (napari pins compatible PyQt6/Qt versions), rather than napari[qt], which would follow napari to a future binding untested here. CI now gets Qt from the extra, like users do.
mouseReleaseEvent is also connected to scene().sigMouseClicked, which passes a pyqtgraph MouseClickEvent. Its pos() is item-local (or fails if no item took the click) and is a QPointF that mapToScene can't take, so the always-evaluated f-string raised on every ordinary click.
jan-glx
force-pushed
the
jangleixner/qt6
branch
from
November 9, 2026 13:42
289a34e to
38986af
Compare
jan-glx
marked this pull request as ready for review
November 9, 2026 13:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #405.
napari 0.10 requires Qt >= 6.7 and no longer has a
pyqt5extra. Sopip install napari-spatialdata[all]installs no Qt binding at all (pip only warns), and an env with PyQt5 fails atimport napari._qt. Our CI didn't catch this becausetox.iniinstallsPyQt5directly.Changes
setup.cfg:all = napari[pyqt5]becomesnapari[pyqt6]. That pins the binding napari-spatialdata is tested with, and napari's extra keeps compatible PyQt6/Qt versions.napari[qt]would instead follow napari to whatever binding it defaults to next, possibly before this plugin's Qt code (widgets, pyqtgraph) is tested on it. README updated to match.tox.ini: drop the explicitPyQt5. CI now gets Qt from theallextra, the same way users do._scatterwidgets.py(user-facing bug on Qt6): ROI drawing in the scatter widget passedevent.pos()(QPoint) tomapSceneToView/sceneBoundingRect().contains. PyQt6 no longer convertsQPointtoQPointFimplicitly, so every press/move/release while drawing raisedTypeErrorand no ROI was created.scene_pos = self.mapToScene(event.pos()), which is aQPointFon every binding, and use it throughout.mouseReleaseEventis also called byscene().sigMouseClickedwith a pyqtgraphMouseClickEvent(whosepos()mapToScenecan't take), so its position debug log is now limited toQMouseEvent.event.pos()was used as a scene position, mixed with ascene_posvariable holding the same value. That only worked because pyqtgraph's defaultautoPixelRangekeeps scene coordinates equal to viewport pixels, so the values don't change.fprefix.test_old_annotationpatched"PyQt5.QtWidgets.QMessageBox.question". It now usesmocker.patch.object(QtWidgets.QMessageBox, ...)via qtpy.send_mouse_eventnow passes aQPointFtoQMouseEvent.Tested
Tested in a Linux env with napari 0.10.0 + PyQt6 6.12.0 (headless, conftest's
QT_QPA_PLATFORM=offscreen):ImportErrorin conftest with PyQt5. With PyQt6 but without the code changes: 3 failed (test_old_annotation,test_roi_from_mouse_events,test_remove_roi_double_click).QT_API=pyqt5): 87 passed, so nothing changes on the old binding.pip install --dry-run -e ".[all]"resolves napari 0.10.0 + PyQt6 6.12.0 with no warnings. Thepyqt6extra exists back to napari 0.6.2, the minimum allowed version.Found via the scverse integration tests (scverse/spatialdata-integration-testing#26).