add PyQt6 to CI

skip tests that don't work for Qt6

add Qt6 and remove Qt4 from test_examples.py

update README.md

switch mouse tests to use QPointF

this eliminates all the special casing for different bindings
This commit is contained in:
KIU Shueng Chuan 2021-01-18 12:38:28 +08:00
parent eec411a3c6
commit 6c760f3de1
7 changed files with 20 additions and 32 deletions

View File

@ -31,7 +31,7 @@ jobs:
numpy-version: "~=1.19.0" numpy-version: "~=1.19.0"
- python-version: "3.9" - python-version: "3.9"
qt-lib: "pyqt" qt-lib: "pyqt"
qt-version: "PyQt5~=5.15" qt-version: "PyQt6"
numpy-version: "~=1.19.0" numpy-version: "~=1.19.0"
- python-version: "3.9" - python-version: "3.9"
qt-lib: "pyside" qt-lib: "pyside"

View File

@ -9,7 +9,7 @@ PyQtGraph
[![Total alerts](https://img.shields.io/lgtm/alerts/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/alerts/) [![Total alerts](https://img.shields.io/lgtm/alerts/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/alerts/)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/context:python) [![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/context:python)
A pure-Python graphics library for PyQt5/PySide2/PySide6 A pure-Python graphics library for PyQt5/PyQt6/PySide2/PySide6
Copyright 2020 Luke Campagnola, University of North Carolina at Chapel Hill Copyright 2020 Luke Campagnola, University of North Carolina at Chapel Hill
@ -36,7 +36,7 @@ Currently this means:
* Python 3.7+ * Python 3.7+
* Qt 5.12-6.0 * Qt 5.12-6.0
* Required * Required
* PyQt5, PySide2 or PySide6 * PyQt5, PyQt6, PySide2 or PySide6
* `numpy` 1.17+ * `numpy` 1.17+
* Optional * Optional
* `scipy` for image processing * `scipy` for image processing
@ -57,8 +57,9 @@ The following table represents the python environments we test in our CI system.
| PySide2-5.12 | :white_check_mark: | :x: | :x: | | PySide2-5.12 | :white_check_mark: | :x: | :x: |
| PyQt5-5.12 | :white_check_mark: | :x: | :x: | | PyQt5-5.12 | :white_check_mark: | :x: | :x: |
| PySide2-5.15 | :x: | :white_check_mark: | :x: | | PySide2-5.15 | :x: | :white_check_mark: | :x: |
| PyQt5-5.15 | :x: | :white_check_mark: | :white_check_mark: | | PyQt5-5.15 | :x: | :white_check_mark: | :x: |
| PySide6-6.0 | :x: | :x: | :white_check_mark: | | PySide6-6.0 | :x: | :x: | :white_check_mark: |
| PyQt6-6.0 | :x: | :x: | :white_check_mark: |
Support Support
------- -------

View File

@ -35,10 +35,10 @@ def buildFileList(examples, files=None):
path = os.path.abspath(os.path.dirname(__file__)) path = os.path.abspath(os.path.dirname(__file__))
files = sorted(set(buildFileList(examples))) files = sorted(set(buildFileList(examples)))
frontends = { frontends = {
Qt.PYQT4: False,
Qt.PYQT5: False, Qt.PYQT5: False,
Qt.PYSIDE: False, Qt.PYQT6: False,
Qt.PYSIDE2: False Qt.PYSIDE2: False,
Qt.PYSIDE6: False,
} }
# sort out which of the front ends are available # sort out which of the front ends are available
for frontend in frontends.keys(): for frontend in frontends.keys():
@ -66,13 +66,6 @@ conditionalExamples = {
False, False,
reason="Test is being problematic on CI machines" reason="Test is being problematic on CI machines"
), ),
"optics_demos.py": exceptionCondition(
not frontends[Qt.PYSIDE],
reason=(
"Test fails due to PySide bug: ",
"https://bugreports.qt.io/browse/PYSIDE-671"
)
),
'GLVolumeItem.py': exceptionCondition( 'GLVolumeItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not(platform.system() == "Darwin" and
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and

View File

@ -7,7 +7,7 @@ pytest.importorskip("matplotlib")
app = pg.mkQApp() app = pg.mkQApp()
skip_qt6 = pytest.mark.skipif( skip_qt6 = pytest.mark.skipif(
pg.QT_LIB == "PySide6", pg.QT_LIB in ["PySide6", "PyQt6"],
reason= ( reason= (
"Matplotlib has no Qt6 support yet, " "Matplotlib has no Qt6 support yet, "
"see https://github.com/matplotlib/matplotlib/pull/19255" "see https://github.com/matplotlib/matplotlib/pull/19255"

View File

@ -63,8 +63,8 @@ def test_mouseInteraction():
plt.setYRange(-10, 10) plt.setYRange(-10, 10)
# test horizontal drag # test horizontal drag
pos = plt.plotItem.vb.mapViewToScene(pg.Point(0,5)).toPoint() pos = plt.plotItem.vb.mapViewToScene(pg.Point(0,5))
pos2 = pos - QtCore.QPoint(200, 200) pos2 = pos - QtCore.QPointF(200, 200)
mouseMove(plt, pos) mouseMove(plt, pos)
assert vline.mouseHovering is True and hline.mouseHovering is False assert vline.mouseHovering is True and hline.mouseHovering is False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
@ -72,17 +72,17 @@ def test_mouseInteraction():
assert abs(vline.value() - plt.plotItem.vb.mapSceneToView(pos2).x()) <= px assert abs(vline.value() - plt.plotItem.vb.mapSceneToView(pos2).x()) <= px
# test missed drag # test missed drag
pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint() pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0))
pos = pos + QtCore.QPoint(0, 6) pos = pos + QtCore.QPointF(0, 6)
pos2 = pos + QtCore.QPoint(-20, -20) pos2 = pos + QtCore.QPointF(-20, -20)
mouseMove(plt, pos) mouseMove(plt, pos)
assert vline.mouseHovering is False and hline.mouseHovering is False assert vline.mouseHovering is False and hline.mouseHovering is False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
assert hline.value() == 0 assert hline.value() == 0
# test vertical drag # test vertical drag
pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint() pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0))
pos2 = pos - QtCore.QPoint(50, 50) pos2 = pos - QtCore.QPointF(50, 50)
mouseMove(plt, pos) mouseMove(plt, pos)
assert vline.mouseHovering is False and hline.mouseHovering is True assert vline.mouseHovering is False and hline.mouseHovering is True
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
@ -90,8 +90,8 @@ def test_mouseInteraction():
assert abs(hline.value() - plt.plotItem.vb.mapSceneToView(pos2).y()) <= px assert abs(hline.value() - plt.plotItem.vb.mapSceneToView(pos2).y()) <= px
# test non-interactive line # test non-interactive line
pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,-1)).toPoint() pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,-1))
pos2 = pos - QtCore.QPoint(50, 50) pos2 = pos - QtCore.QPointF(50, 50)
mouseMove(plt, pos) mouseMove(plt, pos)
assert hline2.mouseHovering == False assert hline2.mouseHovering == False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)

View File

@ -257,7 +257,7 @@ def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50.,
assert im1.dtype == im2.dtype assert im1.dtype == im2.dtype
if pxCount == -1: if pxCount == -1:
if QT_LIB in {'PyQt5', 'PySide2', 'PySide6'}: if QT_LIB in {'PyQt5', 'PySide2', 'PySide6', 'PyQt6'}:
# Qt5 generates slightly different results; relax the tolerance # Qt5 generates slightly different results; relax the tolerance
# until test images are updated. # until test images are updated.
pxCount = int(im1.shape[0] * im1.shape[1] * 0.01) pxCount = int(im1.shape[0] * im1.shape[1] * 0.01)

View File

@ -1,5 +1,5 @@
import time import time
from ..Qt import QtCore, QtGui, QtTest, QT_LIB from ..Qt import QtCore, QtGui, QtTest
def resizeWindow(win, w, h, timeout=2.0): def resizeWindow(win, w, h, timeout=2.0):
@ -32,8 +32,6 @@ def mousePress(widget, pos, button, modifier=None):
widget = widget.viewport() widget = widget.viewport()
if modifier is None: if modifier is None:
modifier = QtCore.Qt.NoModifier modifier = QtCore.Qt.NoModifier
if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, button, QtCore.Qt.NoButton, modifier) event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, button, QtCore.Qt.NoButton, modifier)
QtGui.QApplication.sendEvent(widget, event) QtGui.QApplication.sendEvent(widget, event)
@ -43,8 +41,6 @@ def mouseRelease(widget, pos, button, modifier=None):
widget = widget.viewport() widget = widget.viewport()
if modifier is None: if modifier is None:
modifier = QtCore.Qt.NoModifier modifier = QtCore.Qt.NoModifier
if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, button, QtCore.Qt.NoButton, modifier) event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, button, QtCore.Qt.NoButton, modifier)
QtGui.QApplication.sendEvent(widget, event) QtGui.QApplication.sendEvent(widget, event)
@ -56,8 +52,6 @@ def mouseMove(widget, pos, buttons=None, modifier=None):
modifier = QtCore.Qt.NoModifier modifier = QtCore.Qt.NoModifier
if buttons is None: if buttons is None:
buttons = QtCore.Qt.NoButton buttons = QtCore.Qt.NoButton
if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, buttons, modifier) event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, buttons, modifier)
QtGui.QApplication.sendEvent(widget, event) QtGui.QApplication.sendEvent(widget, event)