First pass at implementing the diff from PR307
This commit is contained in:
parent
b41c4a71e5
commit
ce6da3e93f
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import time
|
||||||
import weakref
|
import weakref
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -8,6 +9,9 @@ from .. import functions as fn
|
||||||
from .. import ptime as ptime
|
from .. import ptime as ptime
|
||||||
from .mouseEvents import *
|
from .mouseEvents import *
|
||||||
from .. import debug as debug
|
from .. import debug as debug
|
||||||
|
from .. import getConfigOption
|
||||||
|
|
||||||
|
getMillis = lambda: int(round(time.time() * 1000))
|
||||||
|
|
||||||
|
|
||||||
if hasattr(QtCore, 'PYQT_VERSION'):
|
if hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
|
@ -114,6 +118,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
||||||
self.contextMenu[0].triggered.connect(self.showExportDialog)
|
self.contextMenu[0].triggered.connect(self.showExportDialog)
|
||||||
|
|
||||||
self.exportDialog = None
|
self.exportDialog = None
|
||||||
|
self._lastMoveEventTime = 0
|
||||||
|
|
||||||
def render(self, *args):
|
def render(self, *args):
|
||||||
self.prepareForPaint()
|
self.prepareForPaint()
|
||||||
|
@ -161,39 +166,60 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
||||||
if i.isEnabled() and i.isVisible() and int(i.flags() & i.ItemIsFocusable) > 0:
|
if i.isEnabled() and i.isVisible() and int(i.flags() & i.ItemIsFocusable) > 0:
|
||||||
i.setFocus(QtCore.Qt.MouseFocusReason)
|
i.setFocus(QtCore.Qt.MouseFocusReason)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def _moveEventIsAllowed(self):
|
||||||
|
# For ignoring events that are too close together
|
||||||
|
|
||||||
|
# Max number of events per second
|
||||||
|
rateLimit = getConfigOption('mouseRateLimit')
|
||||||
|
if rateLimit <= 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Delay between events (in milliseconds)
|
||||||
|
delay = 1000.0 / rateLimit
|
||||||
|
if getMillis() - self._lastMoveEventTime >= delay:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def mouseMoveEvent(self, ev):
|
def mouseMoveEvent(self, ev):
|
||||||
self.sigMouseMoved.emit(ev.scenePos())
|
# ignore high frequency events
|
||||||
|
if self._moveEventIsAllowed():
|
||||||
## First allow QGraphicsScene to deliver hoverEnter/Move/ExitEvents
|
self._lastMoveEventTime = getMillis()
|
||||||
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
|
self.sigMouseMoved.emit(ev.scenePos())
|
||||||
|
|
||||||
## Next deliver our own HoverEvents
|
# First allow QGraphicsScene to eliver hoverEvent/Move/Exit Events
|
||||||
self.sendHoverEvents(ev)
|
|
||||||
|
|
||||||
if int(ev.buttons()) != 0: ## button is pressed; send mouseMoveEvents and mouseDragEvents
|
|
||||||
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
|
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
|
||||||
if self.mouseGrabberItem() is None:
|
# Next Deliver our own Hover Events
|
||||||
now = ptime.time()
|
self.sendHoverEvents(ev)
|
||||||
init = False
|
if int(ev.buttons()) != 0:
|
||||||
## keep track of which buttons are involved in dragging
|
# button is pressed' send mouseMoveEvents and mouseDragEvents
|
||||||
for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MidButton, QtCore.Qt.RightButton]:
|
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
|
||||||
if int(ev.buttons() & btn) == 0:
|
if self.mouseGrabberItem() is None:
|
||||||
continue
|
now = ptime.time()
|
||||||
if int(btn) not in self.dragButtons: ## see if we've dragged far enough yet
|
init = False
|
||||||
cev = [e for e in self.clickEvents if int(e.button()) == int(btn)]
|
## keep track of which buttons are involved in dragging
|
||||||
if cev:
|
for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MidButton, QtCore.Qt.RightButton]:
|
||||||
cev = cev[0]
|
if int(ev.buttons() & btn) == 0:
|
||||||
dist = Point(ev.scenePos() - cev.scenePos()).length()
|
continue
|
||||||
if dist == 0 or (dist < self._moveDistance and now - cev.time() < self.minDragTime):
|
if int(btn) not in self.dragButtons: ## see if we've dragged far enough yet
|
||||||
continue
|
cev = [e for e in self.clickEvents if int(e.button()) == int(btn)]
|
||||||
init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True
|
if cev:
|
||||||
self.dragButtons.append(int(btn))
|
cev = cev[0]
|
||||||
|
dist = Point(ev.scenePos() - cev.scenePos()).length()
|
||||||
## If we have dragged buttons, deliver a drag event
|
if dist == 0 or (dist < self._moveDistance and now - cev.time() < self.minDragTime):
|
||||||
if len(self.dragButtons) > 0:
|
continue
|
||||||
if self.sendDragEvent(ev, init=init):
|
init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True
|
||||||
ev.accept()
|
self.dragButtons.append(int(btn))
|
||||||
|
## if we have dragged buttons, deliver a drag event
|
||||||
|
if len(self.dragButtons) > 0:
|
||||||
|
if self.sendDragEvent(ev, init=init):
|
||||||
|
ev.accept()
|
||||||
|
|
||||||
|
else:
|
||||||
|
QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
|
||||||
|
# if you do not accept event (which is ignored) then cursor will disappear
|
||||||
|
ev.accept()
|
||||||
|
|
||||||
def leaveEvent(self, ev): ## inform items that mouse is gone
|
def leaveEvent(self, ev): ## inform items that mouse is gone
|
||||||
if len(self.dragButtons) == 0:
|
if len(self.dragButtons) == 0:
|
||||||
|
|
|
@ -56,6 +56,7 @@ CONFIG_OPTIONS = {
|
||||||
'exitCleanup': True, ## Attempt to work around some exit crash bugs in PyQt and PySide
|
'exitCleanup': True, ## Attempt to work around some exit crash bugs in PyQt and PySide
|
||||||
'enableExperimental': False, ## Enable experimental features (the curious can search for this key in the code)
|
'enableExperimental': False, ## Enable experimental features (the curious can search for this key in the code)
|
||||||
'crashWarning': False, # If True, print warnings about situations that may result in a crash
|
'crashWarning': False, # If True, print warnings about situations that may result in a crash
|
||||||
|
'mouseRateLimit': 100, # For ignoring frequent mouse events, max number of mouse move events per second, if <= 0, then it is switched off
|
||||||
'imageAxisOrder': 'col-major', # For 'row-major', image data is expected in the standard (row, col) order.
|
'imageAxisOrder': 'col-major', # For 'row-major', image data is expected in the standard (row, col) order.
|
||||||
# For 'col-major', image data is expected in reversed (col, row) order.
|
# For 'col-major', image data is expected in reversed (col, row) order.
|
||||||
# The default is 'col-major' for backward compatibility, but this may
|
# The default is 'col-major' for backward compatibility, but this may
|
||||||
|
|
|
@ -5,16 +5,19 @@ pg.mkQApp()
|
||||||
|
|
||||||
|
|
||||||
def test_InfiniteLine():
|
def test_InfiniteLine():
|
||||||
|
# disable delay of mouse move events because events is called immediately in test
|
||||||
|
pg.setConfigOption('mouseRateLimit', -1)
|
||||||
|
|
||||||
# Test basic InfiniteLine API
|
# Test basic InfiniteLine API
|
||||||
plt = pg.plot()
|
plt = pg.plot()
|
||||||
plt.setXRange(-10, 10)
|
plt.setXRange(-10, 10)
|
||||||
plt.setYRange(-10, 10)
|
plt.setYRange(-10, 10)
|
||||||
plt.resize(600, 600)
|
plt.resize(600, 600)
|
||||||
|
|
||||||
# seemingly arbitrary requirements; might need longer wait time for some platforms..
|
# seemingly arbitrary requirements; might need longer wait time for some platforms..
|
||||||
QtTest.QTest.qWaitForWindowShown(plt)
|
QtTest.QTest.qWaitForWindowShown(plt)
|
||||||
QtTest.QTest.qWait(100)
|
QtTest.QTest.qWait(100)
|
||||||
|
|
||||||
vline = plt.addLine(x=1)
|
vline = plt.addLine(x=1)
|
||||||
assert vline.angle == 90
|
assert vline.angle == 90
|
||||||
br = vline.mapToView(QtGui.QPolygonF(vline.boundingRect()))
|
br = vline.mapToView(QtGui.QPolygonF(vline.boundingRect()))
|
||||||
|
@ -29,14 +32,14 @@ def test_InfiniteLine():
|
||||||
assert vline.value() == 2
|
assert vline.value() == 2
|
||||||
vline.setPos(pg.Point(4, -5))
|
vline.setPos(pg.Point(4, -5))
|
||||||
assert vline.value() == 4
|
assert vline.value() == 4
|
||||||
|
|
||||||
oline = pg.InfiniteLine(angle=30)
|
oline = pg.InfiniteLine(angle=30)
|
||||||
plt.addItem(oline)
|
plt.addItem(oline)
|
||||||
oline.setPos(pg.Point(1, -1))
|
oline.setPos(pg.Point(1, -1))
|
||||||
assert oline.angle == 30
|
assert oline.angle == 30
|
||||||
assert oline.pos() == pg.Point(1, -1)
|
assert oline.pos() == pg.Point(1, -1)
|
||||||
assert oline.value() == [1, -1]
|
assert oline.value() == [1, -1]
|
||||||
|
|
||||||
# test bounding rect for oblique line
|
# test bounding rect for oblique line
|
||||||
br = oline.mapToScene(oline.boundingRect())
|
br = oline.mapToScene(oline.boundingRect())
|
||||||
pos = oline.mapToScene(pg.Point(2, 0))
|
pos = oline.mapToScene(pg.Point(2, 0))
|
||||||
|
@ -55,7 +58,7 @@ def test_mouseInteraction():
|
||||||
hline2 = plt.addLine(y=-1, movable=False)
|
hline2 = plt.addLine(y=-1, movable=False)
|
||||||
plt.setXRange(-10, 10)
|
plt.setXRange(-10, 10)
|
||||||
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)).toPoint()
|
||||||
pos2 = pos - QtCore.QPoint(200, 200)
|
pos2 = pos - QtCore.QPoint(200, 200)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user