[Python] draggable line with multiple break points

Discussão em 'Python' iniciado por Stack, Junho 19, 2025.

  1. Stack

    Stack Membro Participativo

    I have a application very similar to the following question:Draw half infinite lines?

    I would like to have a infinite line with multiple thresholds.

    [​IMG]

    The solution provided in the question is a great starting point: https://stackoverflow.com/a/37836348/7163293

    I attempted to make the lines movable by modifying the movable attribute in __init__ and add a setMovable method just as the source code in source:

    http://www.pyqtgraph.org/documentat.../graphicsItems/InfiniteLine.html#InfiniteLine

    from pyqtgraph.Qt import QtGui
    import numpy as np
    import pyqtgraph as pg

    class InfiniteLineWithBreak(pg.GraphicsObject):

    def __init__(self, changeX, levelsY, pen=None):
    pg.GraphicsObject.__init__(self)

    self.changeX = changeX
    self.levelsY = levelsY

    self.maxRange = [None, None]
    self.moving = False
    self.movable = True
    self.setMovable(self.movable)
    self.mouseHovering = False

    pen = (200, 200, 100)
    self.setPen(pen)
    self.setHoverPen(color=(255,0,0), width=self.pen.width())
    self.currentPen = self.pen

    def setMovable(self, m):
    """Set whether the line is movable by the user."""
    self.movable = m
    self.setAcceptHoverEvents(m)


    def setBounds(self, bounds):
    self.maxRange = bounds
    self.setValue(self.value())

    def setPen(self, *args, **kwargs):
    self.pen = pg.fn.mkPen(*args, **kwargs)
    if not self.mouseHovering:
    self.currentPen = self.pen
    self.update()

    def setHoverPen(self, *args, **kwargs):
    self.hoverPen = pg.fn.mkPen(*args, **kwargs)
    if self.mouseHovering:
    self.currentPen = self.hoverPen
    self.update()

    def boundingRect(self):
    br = self.viewRect()
    return br.normalized()

    def paint(self, p, *args):
    br = self.boundingRect()
    p.setPen(self.currentPen)
    # three lines (left border to change point, change point vertical, change point to right)
    p.drawLine(pg.Point(br.left(), self.levelsY[0]), pg.Point(self.changeX, self.levelsY[0]))
    p.drawLine(pg.Point(self.changeX, self.levelsY[0]), pg.Point(self.changeX, self.levelsY[1]))
    p.drawLine(pg.Point(self.changeX, self.levelsY[1]), pg.Point(br.right(), self.levelsY[1]))

    def dataBounds(self, axis, frac=1.0, orthoRange=None):
    if axis == 0:
    return None ## x axis should never be auto-scaled
    else:
    return (0,0)

    def setMouseHover(self, hover):
    pass

    app = QtGui.QApplication([])
    w = pg.GraphicsWindow()
    w.resize(1000, 600)
    v = w.addPlot(y=np.random.normal(size=100))
    v.addItem(InfiniteLineWithBreak(changeX=50, levelsY=(-1, 1)))
    app.exec_()


    However, the line is still not movable after the modifications.So I am kind of stuck here. Would someone be able to provide some pointers?

    Also, ideally, the line on the applications should be movable by segments. So when the user drag a line, only the portion in between break points are moving. So ideally I would like to have something like:

    Draggable line with draggable points

    in my application. Ideally it would look something like

    [​IMG]

    with the threshold point level (TH_Px_L1) draggable but not the timing (TH_Px_T1), so the points can only move vertically.

    If someone can also help on the second item and provide some pointers or solution that will be very helpful.

    Continue reading...

Compartilhe esta Página