Attempt number 3: I almost have it doing what I want! I looked at what 
PlotCurveItem does to make the curveClicked signal, and saw I had to make a 
stroke path.

The *last* piece of the puzzle is how to inform the graphics handler that 
my spot size extends a bit beyond the natural bounding rect. Does anyone 
know of a way to make this happen? I.e. the programming logic works, but 
the check for self.itemsNearEvent() in the graphics scene fails for a click 
near the top-right shape.
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, QtCore, QtGui
import numpy as np

class CustScatter(pg.ScatterPlotItem):
  def pointsAt(self, pos: QtCore.QPointF):
    # if isinstance(pos, QtCore.QPointF):
    #   halfSz = 0.25
    #   pos = QtCore.QRectF(pos.x()-halfSz, pos.y()-halfSz, 2*halfSz, 
2*halfSz)
    pts = []
    for spot in self.points(): # type: pg.SpotItem
      symb = QtGui.QPainterPath(spot.symbol())
      symb.translate(spot.pos())
      stroker = QtGui.QPainterPathStroker()
      mousePath = stroker.createStroke(symb)
      if mousePath.contains(pos):
        pts.append(spot)
    return pts[::-1]

tri = np.array([[0,2.3,0,1,4,5,0], [0,4,4,8,8,3,0]]).T
tris = []
xyLocs = []
datas = []
for ii in np.arange(0, 16, 5):
  curTri = tri + ii
  tris.append(curTri)
  xyLocs.append(curTri.min(0))
  datas.append(ii)

def ptsClicked(item, pts):
  print(f'ID {pts[0].data()} Clicked!')

def makeSymbol(verts: np.ndarray):
  outSymbol = QtGui.QPainterPath()
  symPath = pg.arrayToQPath(*verts.T)
  outSymbol.addPath(symPath)
  # From pyqtgraph.examples for plotting text
  br = outSymbol.boundingRect()
  tr = QtGui.QTransform()
  tr.translate(-br.x(), -br.y())
  outSymbol = tr.map(outSymbol)
  return outSymbol

app = pg.mkQApp()
pg.setConfigOption('background', 'w')

symbs = []
for xyLoc, tri in zip(xyLocs, tris):
  symbs.append(makeSymbol(tri))

xyLocs = np.vstack(xyLocs)
tri2 = pg.PlotDataItem()
scat = CustScatter(*xyLocs.T, symbol=symbs, data=datas, connect='finite',
                   pxMode=False, brush=None, pen=pg.mkPen(width=5), size=1)
scat.sigClicked.connect(ptsClicked)
# Now each 'point' is one of the triangles, hopefully

w = pg.PlotWindow()
w.plotItem.addItem(scat)
plt: pg.PlotItem = w.plotItem
plt.showGrid(True, True, 1)
w.show()
app.exec()




On Saturday, June 6, 2020 at 9:44:36 PM UTC-4, Nathan Jessurun wrote:
>
> Hi there,
>
> My overall goal is to have several clickable regions overlaid on an image, 
> and if the plot boundary of any region is clicked I get a signal with the 
> ID of that region. Something like this:
> I tried making each boundary a separate plot data item, but I have 1000s 
> of bounds that update frequently so it lagged a ton. So, I just used 
> connect='finite' within the same plot item to make it much faster.
>
> However, now I can't give a separate ID to each boundary. I have to make 
> the vertices stand out, and connect to sigclicked(...pts) instead:
>
> This works, but I'd love to be able to click anywhere on one of the line 
> segments for the same effect. Is there any way to make this happen?
>
> Relevant code is just a PlotDataItem on a plot widget.
>
> Thanks!
>

-- 
You received this message because you are subscribed to the Google Groups 
"pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pyqtgraph/21e33c38-4622-40d9-9939-adc2adf007abo%40googlegroups.com.

Reply via email to