[英]draggable line with multiple break points
我有一個非常類似於以下問題的應用程序: 繪制一半無限的線條?
我想擁有一個具有多個閾值的無限線。
問題中提供的解決方案是一個很好的起點: https : //stackoverflow.com/a/37836348/7163293
我嘗試通過修改__init__
的movable
屬性來使行可movable
,並添加一個setMovable
方法,就像源代碼中的源代碼一樣:
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_()
然而,修改后線仍然不能移動。所以我有點被困在這里。 有人能提供一些指示嗎?
此外,理想情況下,應用程序上的行應按段移動。 因此,當用戶拖動一條線時,只有斷點之間的部分在移動。 理想情況下,我希望有類似的東西:
在我的申請中。 理想情況下,它看起來像
閾值點水平(TH_Px_L1)可拖動但不是時間(TH_Px_T1),因此點只能垂直移動。
如果有人也可以幫助第二項,並提供一些非常有幫助的指針或解決方案。
散點圖類型與繪制圖形的圖形類似,但是連接線位於i點點和它們連接的i + 1點點之間。 然后我們將運動僅限制在垂直軸上,因為這是作者的要求。
import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
pg.setConfigOptions(antialias=True)
w = pg.GraphicsWindow()
w.setWindowTitle('Draggable')
class Graph(pg.GraphItem):
def __init__(self):
self.dragPoint = None
self.dragOffset = None
pg.GraphItem.__init__(self)
def setData(self, **kwds):
self.data = kwds
if 'pos' in self.data:
npts = self.data['pos'].shape[0]
self.data['adj'] = np.column_stack((np.arange(0, npts-1), np.arange(1, npts)))
self.data['data'] = np.empty(npts, dtype=[('index', int)])
self.data['data']['index'] = np.arange(npts)
self.updateGraph()
def updateGraph(self):
pg.GraphItem.setData(self, **self.data)
def mouseDragEvent(self, ev):
if ev.button() != QtCore.Qt.LeftButton:
ev.ignore()
return
if ev.isStart():
pos = ev.buttonDownPos()
pts = self.scatter.pointsAt(pos)
if len(pts) == 0:
ev.ignore()
return
self.dragPoint = pts[0]
ind = pts[0].data()[0]
self.dragOffset = self.data['pos'][ind][1] - pos[1]
elif ev.isFinish():
self.dragPoint = None
return
else:
if self.dragPoint is None:
ev.ignore()
return
ind = self.dragPoint.data()[0]
self.data['pos'][ind][1] = ev.pos()[1] + self.dragOffset
self.updateGraph()
ev.accept()
g = Graph()
v = w.addPlot()
v.addItem(g)
x = np.linspace(1, 100, 40)
pos = np.column_stack((x, np.sin(x)))
g.setData(pos=pos, size=10, pxMode=True)
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.