Search code examples
plothandlepolylinepyqtgraph

PyQtGraph PolyLineROI maxBounds Not Working


I have a PolyLineROI in a PlotItem and am trying to limit the handles to moving only within the bounds of the plot. I have tried to use the maxBounds argument, but this does not work (the handles still move outside the graph):

Code:

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

app = pg.mkQApp('Plot')

window = pg.GraphicsLayoutWidget(show=True, size=(400,400), border=False, title='Plot')
plt = window.addPlot(title='Plot')

polyline = pg.PolyLineROI(
    [[0,0], [10,10], [10,30], [30,10]],
    closed=False,
    maxBounds=QtCore.QRectF(0,0,30,30)
)

plt.addItem(polyline)

plt.disableAutoRange('xy')
plt.autoRange()

if __name__ == "__main__":
    pg.exec()

Problem:

Handles_Move_Outside_Graph

I have seen this question asked on these mailing lists:

  1. Google Group
  2. Mail Archive Google Group

but they don't have any answers and this has not been asked here.

How can I prevent the handles from moving outside the bounds of the graph?


Solution

  • To do this, you must subclass PolyLineROI and override checkPointMove:

    Code:

    import pyqtgraph as pg
    from pyqtgraph.Qt import QtCore
    
    class GraphPolyLine(pg.PolyLineROI):
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def checkPointMove(self, handle, pos, modifiers):
            if self.maxBounds is not None:
                pt = self.getViewBox().mapSceneToView(pos)
            
                if not self.maxBounds.contains(pt.x(), pt.y()):
                    return False
    
            return True
    
    app = pg.mkQApp("ROI Examples")
    
    window = pg.GraphicsLayoutWidget(show=True, size=(400,400), border=False, title='Plot')
    
    plt = window.addPlot(title="Plot")
    plt.setMouseEnabled(False, False)  # Disable zoom and pan
    
    polyline = GraphPolyLine(
        [[0,0], [10,10], [10,30], [30,10]],
        closed=False,
        maxBounds = QtCore.QRectF(0, 0, 30, 30)
    )
    
    plt.addItem(polyline)
    plt.disableAutoRange('xy')
    plt.autoRange()
    
    if __name__ == "__main__":
        pg.exec()
    

    Solution:

    From pyqtgraph.graphicsItems.ROI, we see

    checkPointMove

    WorkingSolution