From 2b9f613eab82494c3d70a3a90067748e061f3fb0 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 3 Feb 2016 23:13:58 -0800 Subject: [PATCH] Added unit tests checking infiniteline interactivity --- pyqtgraph/GraphicsScene/GraphicsScene.py | 5 +- .../graphicsItems/tests/test_InfiniteLine.py | 41 ++++++++++++++ pyqtgraph/tests/__init__.py | 1 + pyqtgraph/tests/ui_testing.py | 55 +++++++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 pyqtgraph/graphicsItems/tests/test_InfiniteLine.py create mode 100644 pyqtgraph/tests/__init__.py create mode 100644 pyqtgraph/tests/ui_testing.py diff --git a/pyqtgraph/GraphicsScene/GraphicsScene.py b/pyqtgraph/GraphicsScene/GraphicsScene.py index 840e3135..bab0f776 100644 --- a/pyqtgraph/GraphicsScene/GraphicsScene.py +++ b/pyqtgraph/GraphicsScene/GraphicsScene.py @@ -98,6 +98,7 @@ class GraphicsScene(QtGui.QGraphicsScene): self.lastDrag = None self.hoverItems = weakref.WeakKeyDictionary() self.lastHoverEvent = None + self.minDragTime = 0.5 # drags shorter than 0.5 sec are interpreted as clicks self.contextMenu = [QtGui.QAction("Export...", self)] self.contextMenu[0].triggered.connect(self.showExportDialog) @@ -173,7 +174,7 @@ class GraphicsScene(QtGui.QGraphicsScene): if int(btn) not in self.dragButtons: ## see if we've dragged far enough yet cev = [e for e in self.clickEvents if int(e.button()) == int(btn)][0] dist = Point(ev.screenPos() - cev.screenPos()) - if dist.length() < self._moveDistance and now - cev.time() < 0.5: + if dist.length() < self._moveDistance and now - cev.time() < self.minDragTime: continue init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True self.dragButtons.append(int(btn)) @@ -186,10 +187,8 @@ class GraphicsScene(QtGui.QGraphicsScene): def leaveEvent(self, ev): ## inform items that mouse is gone if len(self.dragButtons) == 0: self.sendHoverEvents(ev, exitOnly=True) - def mouseReleaseEvent(self, ev): - #print 'sceneRelease' if self.mouseGrabberItem() is None: if ev.button() in self.dragButtons: if self.sendDragEvent(ev, final=True): diff --git a/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py b/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py new file mode 100644 index 00000000..53a4f6ea --- /dev/null +++ b/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py @@ -0,0 +1,41 @@ +import pyqtgraph as pg +from pyqtgraph.Qt import QtTest, QtGui, QtCore +from pyqtgraph.tests import mouseDrag +pg.mkQApp() + +qWait = QtTest.QTest.qWait + + +def test_mouseInteraction(): + plt = pg.plot() + plt.scene().minDragTime = 0 # let us simulate mouse drags very quickly. + vline = plt.addLine(x=0, movable=True) + plt.addItem(vline) + hline = plt.addLine(y=0, movable=True) + plt.setXRange(-10, 10) + plt.setYRange(-10, 10) + + # test horizontal drag + pos = plt.plotItem.vb.mapViewToScene(pg.Point(0,5)).toPoint() + pos2 = pos - QtCore.QPoint(200, 200) + mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) + px = vline.pixelLength(pg.Point(1, 0), ortho=True) + assert abs(vline.value() - plt.plotItem.vb.mapSceneToView(pos2).x()) <= px + + # test missed drag + pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint() + pos = pos + QtCore.QPoint(0, 6) + pos2 = pos + QtCore.QPoint(-20, -20) + mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) + assert hline.value() == 0 + + # test vertical drag + pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint() + pos2 = pos - QtCore.QPoint(50, 50) + mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton) + px = hline.pixelLength(pg.Point(1, 0), ortho=True) + assert abs(hline.value() - plt.plotItem.vb.mapSceneToView(pos2).y()) <= px + + +if __name__ == '__main__': + test_mouseInteraction() diff --git a/pyqtgraph/tests/__init__.py b/pyqtgraph/tests/__init__.py new file mode 100644 index 00000000..7d9ccc9f --- /dev/null +++ b/pyqtgraph/tests/__init__.py @@ -0,0 +1 @@ +from .ui_testing import mousePress, mouseMove, mouseRelease, mouseDrag, mouseClick diff --git a/pyqtgraph/tests/ui_testing.py b/pyqtgraph/tests/ui_testing.py new file mode 100644 index 00000000..383ba4f9 --- /dev/null +++ b/pyqtgraph/tests/ui_testing.py @@ -0,0 +1,55 @@ + +# Functions for generating user input events. +# We would like to use QTest for this purpose, but it seems to be broken. +# See: http://stackoverflow.com/questions/16299779/qt-qgraphicsview-unit-testing-how-to-keep-the-mouse-in-a-pressed-state + +from ..Qt import QtCore, QtGui, QT_LIB + + +def mousePress(widget, pos, button, modifier=None): + if isinstance(widget, QtGui.QGraphicsView): + widget = widget.viewport() + if modifier is None: + 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) + QtGui.QApplication.sendEvent(widget, event) + + +def mouseRelease(widget, pos, button, modifier=None): + if isinstance(widget, QtGui.QGraphicsView): + widget = widget.viewport() + if modifier is None: + 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) + QtGui.QApplication.sendEvent(widget, event) + + +def mouseMove(widget, pos, buttons=None, modifier=None): + if isinstance(widget, QtGui.QGraphicsView): + widget = widget.viewport() + if modifier is None: + modifier = QtCore.Qt.NoModifier + if buttons is None: + 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) + QtGui.QApplication.sendEvent(widget, event) + + +def mouseDrag(widget, pos1, pos2, button, modifier=None): + mouseMove(widget, pos1) + mousePress(widget, pos1, button, modifier) + mouseMove(widget, pos2, button, modifier) + mouseRelease(widget, pos2, button, modifier) + + +def mouseClick(widget, pos, button, modifier=None): + mouseMove(widget, pos) + mousePress(widget, pos, button, modifier) + mouseRelease(widget, pos, button, modifier) +