2017-08-10 34 views
4

我有非常相似的以下问题一个应用程序PyQt的可拖动行:Draw half infinite lines?有多个破发点

我想有多个阈值的无穷线。

enter image description here

在问题提供的解决方案是一个很好的起点:https://stackoverflow.com/a/37836348/7163293

我试图使线移动通过修改__init__movable属性并添加setMovable方法只是作为源代码在源:

http://www.pyqtgraph.org/documentation/_modules/pyqtgraph/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_() 

但是,修改后仍然不能移动。所以我有点卡在这里。会有人能够提供一些指针?

此外,理想情况下,应用程序的行应可以分段移动。所以当用户拖动一条线时,只有中断点之间的部分正在移动。所以,我非常希望有这样的:在我的应用程序

Draggable line with draggable points

。理想情况下,会看起来像

enter image description here

与临界点水平(TH_Px_L1)拖动,但不定时(TH_Px_T1),所以点只能垂直移动。

如果有人也可以帮助第二个项目,并提供一些指针或解决方案,这将是非常有益的。

+0

您必须提供[最小,完整,可验证的示例](https://stackoverflow.com/help/mcve) – eyllanesc

+1

@eyllanesc感谢您的建议。我添加了我正在运行的代码。 – SunnyIsaLearner

+0

你想移动白线还是黄线? – eyllanesc

回答

1

基于this example from docs。

散点图类似于绘制图形的点,但连接线位于它们连接的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_() 

enter image description here

+0

谢谢,它正常工作!像你这样的人使这个社区变得更好。 :) – SunnyIsaLearner

相关问题