Hey guys,

i'm trying to modify the InfLineLabel class so that its x-position is fixed 
and its y-position is relative to the viewbox, just like when a normal 
InflineLabel is attached to a vertical InfiniteLine. If it's parent isn't a 
InfLine, it behaves like it's attached to a horizontal one, meaning it's 
locked to the y-position instead to the x and it can be moved along the 
x-axis instead of the y. I simply cannot find at all where or how the 
alignment of the line is checked. 

The changes are really rudimentary, but i attached the modified class. I'd 
really appreciate if someone could help me out. 

-- 
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/83f95d5c-56c1-4ba8-baf1-8cbf194982aan%40googlegroups.com.
from PyQt5 import QtGui, QtCore
from pyqtgraph.Point import Point
from pyqtgraph.graphicsItems.TextItem import TextItem
from pyqtgraph.graphicsItems.ViewBox import ViewBox
from pyqtgraph import functions as fn
import numpy as np
import weakref
import time


class MyInfLineLabel(TextItem):
    """
    A TextItem that attaches itself to an InfiniteLine.

    This class extends TextItem with the following features:

    * Automatically positions adjacent to the line at a fixed position along
      the line and within the view box.
    * Automatically reformats text when the line value has changed.
    * Can optionally be dragged to change its location along the line.
    * Optionally aligns to its parent line.

    =============== 
==================================================================
    **Arguments:**
    line            The InfiniteLine to which this label will be attached.
    text            String to display in the label. May contain a {value} 
formatting
                    string to display the current value of the line.
    movable         Bool; if True, then the label can be dragged along the line.
    position        Relative position (0.0-1.0) within the view to position the 
label
                    along the line.
    anchors         List of (x,y) pairs giving the text anchor positions that 
should
                    be used when the line is moved to one side of the view or 
the
                    other. This allows text to switch to the opposite side of 
the line
                    as it approaches the edge of the view. These are 
automatically
                    selected for some common cases, but may be specified if the
                    default values give unexpected results.
    =============== 
==================================================================

    All extra keyword arguments are passed to TextItem. A particularly useful
    option here is to use `rotateAxis=(1, 0)`, which will cause the text to
    be automatically rotated parallel to the line.
    """

    def __init__(self, line, value, text="", movable=False, position=0.5, 
anchors=None, **kwds):
        self.line = line
        self.value = value
        self.movable = movable
        self.moving = False
        self.orthoPos = position  # text will always be placed on the line at a 
position relative to view bounds
        self.format = text
        self._endpoints = (None, None)
        if anchors is None:
            anchors = [(0, 0.5), (1, 0.5)]

        self.anchors = anchors
        TextItem.__init__(self, **kwds)
        self.setParentItem(line)
        self.valueChanged()

    def valueChanged(self):
        if not self.isVisible():
            return
        value = self.value
        self.setText(self.format.format(value=value))
        self.updatePosition()

    def getEndpoints(self):
        # calculate points where line intersects view box
        # (in line coordinates)
        if self._endpoints[0] is None:
            lr = self.line.boundingRect()
            pt1 = Point(lr.left(), 0)
            pt2 = Point(lr.right(), 0)

            self._endpoints = (pt1, pt2)
        return self._endpoints

    def updatePosition(self):
        # update text position to relative view location along line
        self._endpoints = (None, None)
        pt1, pt2 = self.getEndpoints()
        if pt1 is None:
            return
        pt = pt2 * self.orthoPos + pt1 * (1 - self.orthoPos)
        self.setPos(pt)

        # update anchor to keep text visible as it nears the view box edge
        vr = self.line.viewRect()
        if vr is not None:
            self.setAnchor(self.anchors[0 if vr.center().y() < 0 else 1])

    def setVisible(self, v):
        TextItem.setVisible(self, v)
        if v:
            self.updateText()
            self.updatePosition()

    def setMovable(self, m):
        """Set whether this label is movable by dragging along the line.
        """
        self.movable = m
        self.setAcceptHoverEvents(m)

    def setPosition(self, p):
        """Set the relative position (0.0-1.0) of this label within the view box
        and along the line.

        For horizontal (angle=0) and vertical (angle=90) lines, a value of 0.0
        places the text at the bottom or left of the view, respectively.
        """
        self.orthoPos = p
        self.updatePosition()

    def setFormat(self, text):
        """Set the text format string for this label.

        May optionally contain "{value}" to include the lines current value
        (the text will be reformatted whenever the line is moved).
        """
        self.format = text
        self.valueChanged()

    def mouseDragEvent(self, ev):
        if self.movable and ev.button() == QtCore.Qt.LeftButton:
            if ev.isStart():
                self._moving = True
                self._cursorOffset = self._posToRel(ev.buttonDownPos())
                self._startPosition = self.orthoPos
            ev.accept()

            if not self._moving:
                return

            rel = self._posToRel(ev.pos())
            self.orthoPos = np.clip(self._startPosition + rel - 
self._cursorOffset, 0, 1)
            self.updatePosition()
            if ev.isFinish():
                self._moving = False

    def mouseClickEvent(self, ev):
        if self.moving and ev.button() == QtCore.Qt.RightButton:
            ev.accept()
            self.orthoPos = self._startPosition
            self.moving = False

    def hoverEvent(self, ev):
        if not ev.isExit() and self.movable:
            ev.acceptDrags(QtCore.Qt.LeftButton)

    def viewTransformChanged(self):
        self.updatePosition()
        TextItem.viewTransformChanged(self)

    def _posToRel(self, pos):
        # convert local position to relative position along line between view 
bounds
        pt1, pt2 = self.getEndpoints()
        if pt1 is None:
            return 0
        view = self.getViewBox()
        pos = self.mapToParent(pos)
        return (pos.x() - pt1.x()) / (pt2.x() - pt1.x())

Reply via email to