Merge branch 'plot_curve_picking' into develop
This commit is contained in:
commit
3b94b0d93b
37
examples/MouseSelection.py
Normal file
37
examples/MouseSelection.py
Normal file
@ -0,0 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Demonstrates selecting plot curves by mouse click
|
||||
"""
|
||||
import initExample ## Add path to library (just for examples; you do not need this)
|
||||
|
||||
import pyqtgraph as pg
|
||||
from pyqtgraph.Qt import QtCore, QtGui
|
||||
import numpy as np
|
||||
|
||||
win = pg.plot()
|
||||
win.setWindowTitle('pyqtgraph example: Plot data selection')
|
||||
|
||||
curves = [
|
||||
pg.PlotCurveItem(y=np.sin(np.linspace(0, 20, 1000)), pen='r', clickable=True),
|
||||
pg.PlotCurveItem(y=np.sin(np.linspace(1, 21, 1000)), pen='g', clickable=True),
|
||||
pg.PlotCurveItem(y=np.sin(np.linspace(2, 22, 1000)), pen='b', clickable=True),
|
||||
]
|
||||
|
||||
def plotClicked(curve):
|
||||
global curves
|
||||
for i,c in enumerate(curves):
|
||||
if c is curve:
|
||||
c.setPen('rgb'[i], width=3)
|
||||
else:
|
||||
c.setPen('rgb'[i], width=1)
|
||||
|
||||
|
||||
for c in curves:
|
||||
win.addItem(c)
|
||||
c.sigClicked.connect(plotClicked)
|
||||
|
||||
## Start Qt event loop unless running in interactive mode or using pyside.
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||
QtGui.QApplication.instance().exec_()
|
@ -53,9 +53,6 @@ class PlotCurveItem(GraphicsObject):
|
||||
"""
|
||||
GraphicsObject.__init__(self, kargs.get('parent', None))
|
||||
self.clear()
|
||||
self.path = None
|
||||
self.fillPath = None
|
||||
self._boundsCache = [None, None]
|
||||
|
||||
## this is disastrous for performance.
|
||||
#self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
|
||||
@ -70,6 +67,7 @@ class PlotCurveItem(GraphicsObject):
|
||||
'name': None,
|
||||
'antialias': pg.getConfigOption('antialias'),\
|
||||
'connect': 'all',
|
||||
'mouseWidth': 8, # width of shape responding to mouse click
|
||||
}
|
||||
self.setClickable(kargs.get('clickable', False))
|
||||
self.setData(*args, **kargs)
|
||||
@ -80,9 +78,17 @@ class PlotCurveItem(GraphicsObject):
|
||||
return ints
|
||||
return interface in ints
|
||||
|
||||
def setClickable(self, s):
|
||||
"""Sets whether the item responds to mouse clicks."""
|
||||
def setClickable(self, s, width=None):
|
||||
"""Sets whether the item responds to mouse clicks.
|
||||
|
||||
The *width* argument specifies the width in pixels orthogonal to the
|
||||
curve that will respond to a mouse click.
|
||||
"""
|
||||
self.clickable = s
|
||||
if width is not None:
|
||||
self.opts['mouseWidth'] = width
|
||||
self._mouseShape = None
|
||||
self._boundingRect = None
|
||||
|
||||
|
||||
def getData(self):
|
||||
@ -148,6 +154,8 @@ class PlotCurveItem(GraphicsObject):
|
||||
w += pen.widthF()*0.7072
|
||||
if spen is not None and spen.isCosmetic() and spen.style() != QtCore.Qt.NoPen:
|
||||
w = max(w, spen.widthF()*0.7072)
|
||||
if self.clickable:
|
||||
w = max(w, self.opts['mouseWidth']//2 + 1)
|
||||
return w
|
||||
|
||||
def boundingRect(self):
|
||||
@ -171,6 +179,7 @@ class PlotCurveItem(GraphicsObject):
|
||||
#px += self._maxSpotWidth * 0.5
|
||||
#py += self._maxSpotWidth * 0.5
|
||||
self._boundingRect = QtCore.QRectF(xmn-px, ymn-py, (2*px)+xmx-xmn, (2*py)+ymx-ymn)
|
||||
|
||||
return self._boundingRect
|
||||
|
||||
def viewTransformChanged(self):
|
||||
@ -328,6 +337,7 @@ class PlotCurveItem(GraphicsObject):
|
||||
|
||||
self.path = None
|
||||
self.fillPath = None
|
||||
self._mouseShape = None
|
||||
#self.xDisp = self.yDisp = None
|
||||
|
||||
if 'name' in kargs:
|
||||
@ -376,12 +386,14 @@ class PlotCurveItem(GraphicsObject):
|
||||
return path
|
||||
|
||||
|
||||
def shape(self):
|
||||
def getPath(self):
|
||||
if self.path is None:
|
||||
try:
|
||||
self.path = self.generatePath(*self.getData())
|
||||
except:
|
||||
x,y = self.getData()
|
||||
if x is None or len(x) == 0 or y is None or len(y) == 0:
|
||||
return QtGui.QPainterPath()
|
||||
self.path = self.generatePath(*self.getData())
|
||||
self.fillPath = None
|
||||
self._mouseShape = None
|
||||
return self.path
|
||||
|
||||
@pg.debug.warnOnException ## raising an exception here causes crash
|
||||
@ -396,14 +408,8 @@ class PlotCurveItem(GraphicsObject):
|
||||
|
||||
x = None
|
||||
y = None
|
||||
if self.path is None:
|
||||
x,y = self.getData()
|
||||
if x is None or len(x) == 0 or y is None or len(y) == 0:
|
||||
return
|
||||
self.path = self.generatePath(x,y)
|
||||
self.fillPath = None
|
||||
path = self.getPath()
|
||||
|
||||
path = self.path
|
||||
profiler('generate path')
|
||||
|
||||
if self._exportOpts is not False:
|
||||
@ -522,13 +528,36 @@ class PlotCurveItem(GraphicsObject):
|
||||
self.xDisp = None ## display values (after log / fft)
|
||||
self.yDisp = None
|
||||
self.path = None
|
||||
self.fillPath = None
|
||||
self._mouseShape = None
|
||||
self._mouseBounds = None
|
||||
self._boundsCache = [None, None]
|
||||
#del self.xData, self.yData, self.xDisp, self.yDisp, self.path
|
||||
|
||||
def mouseShape(self):
|
||||
"""
|
||||
Return a QPainterPath representing the clickable shape of the curve
|
||||
|
||||
"""
|
||||
if self._mouseShape is None:
|
||||
view = self.getViewBox()
|
||||
if view is None:
|
||||
return QtGui.QPainterPath()
|
||||
stroker = QtGui.QPainterPathStroker()
|
||||
path = self.getPath()
|
||||
path = self.mapToItem(view, path)
|
||||
stroker.setWidth(self.opts['mouseWidth'])
|
||||
mousePath = stroker.createStroke(path)
|
||||
self._mouseShape = self.mapFromItem(view, mousePath)
|
||||
return self._mouseShape
|
||||
|
||||
def mouseClickEvent(self, ev):
|
||||
if not self.clickable or ev.button() != QtCore.Qt.LeftButton:
|
||||
return
|
||||
ev.accept()
|
||||
self.sigClicked.emit(self)
|
||||
if self.mouseShape().contains(ev.pos()):
|
||||
ev.accept()
|
||||
self.sigClicked.emit(self)
|
||||
|
||||
|
||||
|
||||
class ROIPlotItem(PlotCurveItem):
|
||||
|
Loading…
Reference in New Issue
Block a user