From 6a5e7cfee5c7743f1ad94f755046a4186d350417 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Mon, 6 Jul 2020 01:27:43 -0700 Subject: [PATCH] ArrowItem performance - Avoid updates that would have no effect - Raise exception on invalid arguments to setStyle --- pyqtgraph/graphicsItems/ArrowItem.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pyqtgraph/graphicsItems/ArrowItem.py b/pyqtgraph/graphicsItems/ArrowItem.py index b272b7fc..e0628d08 100644 --- a/pyqtgraph/graphicsItems/ArrowItem.py +++ b/pyqtgraph/graphicsItems/ArrowItem.py @@ -23,10 +23,11 @@ class ArrowItem(QtGui.QGraphicsPathItem): opts['headLen'] = opts['size'] if 'width' in opts: opts['headWidth'] = opts['width'] + pos = opts.pop('pos', (0, 0)) + defaultOpts = { 'pxMode': True, 'angle': -150, ## If the angle is 0, the arrow points left - 'pos': (0,0), 'headLen': 20, 'headWidth': None, 'tipAngle': 25, @@ -39,8 +40,9 @@ class ArrowItem(QtGui.QGraphicsPathItem): defaultOpts.update(opts) self.setStyle(**defaultOpts) - - self.moveBy(*self.opts['pos']) + + # for backward compatibility + self.setPos(*pos) def setStyle(self, **opts): """ @@ -67,11 +69,25 @@ class ArrowItem(QtGui.QGraphicsPathItem): tailWidth Width of the tail. default=3 pen The pen used to draw the outline of the arrow. brush The brush used to fill the arrow. + pxMode If True, then the arrow is drawn as a fixed size + regardless of the scale of its parents (including + the ViewBox zoom level). ====================== ================================================= """ - self.opts.update(opts) + arrowOpts = ['headLen', 'tipAngle', 'baseAngle', 'tailLen', 'tailWidth', 'headWidth'] + allowedOpts = ['angle', 'pen', 'brush', 'pxMode'] + arrowOpts + needUpdate = False + for k,v in opts.items(): + if k not in allowedOpts: + raise KeyError('Invalid arrow style option "%s"' % k) + if self.opts.get(k) != v: + needUpdate = True + self.opts[k] = v + + if not needUpdate: + return - opt = dict([(k,self.opts[k]) for k in ['headLen', 'headWidth', 'tipAngle', 'baseAngle', 'tailLen', 'tailWidth']]) + opt = dict([(k,self.opts[k]) for k in arrowOpts if k in self.opts]) tr = QtGui.QTransform() tr.rotate(self.opts['angle']) self.path = tr.map(fn.makeArrowPath(**opt)) @@ -86,7 +102,6 @@ class ArrowItem(QtGui.QGraphicsPathItem): else: self.setFlags(self.flags() & ~self.ItemIgnoresTransformations) - def paint(self, p, *args): p.setRenderHint(QtGui.QPainter.Antialiasing) QtGui.QGraphicsPathItem.paint(self, p, *args)