class LineItem(GraphicsPathItem,QtCore.QObject):
sigHoveredEnter = QtCore.Signal(object, object,object)
sigHoveredLeave = QtCore.Signal(object, object)
sigClicked = QtCore.Signal(object, object)
def __init__(self,start=None, end=None, data = None, parent=None, **opts) -> None:
self._start = start
self._end = end
self.data = data
QtCore.QObject.__init__(self)
GraphicsPathItem.__init__(self, parent, **opts)
self.setAcceptHoverEvents(True)
def hoverEnterEvent(self, ev):
self.sigHoveredEnter.emit(self, ev, self.data)
logger.debug('line Enter')
def makePath(self):
path = QtGui.QPainterPath()
path.moveTo(*self._start)
path.lineTo(*self._end)
return path
def mouseClickEvent(self, ev):
self.sigClicked.emit(self, ev, self.data)
logger.debug('line clicked.')
class GraphicsPathItem(QtGui.QGraphicsPathItem):
__metaclass__ = ABCMeta
def __init__(self, parent=None, **opts) -> None:
self.opts = {}
QtGui.QGraphicsPathItem.__init__(self, parent)
defaultOpts = {
'pxMode': False,
'pen': (200,200,200),
'brush': (190, 190, 190),
}
defaultOpts.update(opts)
self.setStyle(**defaultOpts)
def setStyle(self, **opts):
needUpdate = False
for k,v in opts.items():
if self.opts.get(k) != v:
needUpdate = True
self.opts[k] = v
if not needUpdate:
return
tr = QtGui.QTransform()
self.path = tr.map(self.makePath())
self.setPath(self.path)
self.setPen(fn.mkPen(self.opts['pen']))
self.setBrush(fn.mkBrush(self.opts['brush']))
if self.opts['pxMode']:
self.setFlags(self.flags() | self.GraphicsItemFlag.ItemIgnoresTransformations)
else:
self.setFlags(self.flags() & ~self.GraphicsItemFlag.ItemIgnoresTransformations)
@abstractmethod
def makePath(self):
pass
def paint(self, p, *args):
p.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
super().paint(p, *args)
def shape(self):
return self.path
def dataBounds(self, ax, frac, orthoRange=None):
pw = 0
pen = self.pen()
if not pen.isCosmetic():
pw = pen.width() * 0.7072
if self.opts['pxMode']:
return [0,0]
else:
br = self.boundingRect()
if ax == 0:
return [br.left()-pw, br.right()+pw]
else:
return [br.top()-pw, br.bottom()+pw]
def pixelPadding(self):
pad = 0
if self.opts['pxMode']:
br = self.boundingRect()
pad += hypot(br.width(), br.height())
pen = self.pen()
if pen.isCosmetic():
pad += max(1, pen.width()) * 0.7072
return pad