pyqtgraph/pyqtgraph/parametertree/parameterTypes/pen.py

145 lines
5.3 KiB
Python

from .basetypes import WidgetParameterItem
from .. import Parameter
from ... import functions as fn
from ...Qt import QtWidgets, QtGui, QtCore
from ...widgets.PenSelectorDialog import PenSelectorDialog
class PenParameterItem(WidgetParameterItem):
def __init__(self, param, depth):
self.pdialog = PenSelectorDialog(fn.mkPen(param.pen))
self.pdialog.setModal(True)
self.pdialog.accepted.connect(self.penChangeFinished)
super().__init__(param, depth)
self.displayLabel.paintEvent = self.displayPaintEvent
def makeWidget(self):
self.button = QtWidgets.QPushButton()
#larger button
self.button.setFixedWidth(100)
self.button.clicked.connect(self.buttonClicked)
self.button.paintEvent = self.buttonPaintEvent
self.button.value = self.value
self.button.setValue = self.setValue
self.button.sigChanged = None
return self.button
@property
def pen(self):
return self.pdialog.pen
def value(self):
return self.pen
def setValue(self, pen):
self.pdialog.updateParamFromPen(self.pdialog.param, pen)
def updateDisplayLabel(self, value=None):
super().updateDisplayLabel('')
self.displayLabel.update()
self.widget.update()
def buttonClicked(self):
#open up the pen selector dialog
# Copy in case of rejection
prePen = QtGui.QPen(self.pen)
if self.pdialog.exec() != QtWidgets.QDialog.DialogCode.Accepted:
self.pdialog.updateParamFromPen(self.pdialog.param, prePen)
def penChangeFinished(self):
self.param.setValue(self.pdialog.pen)
def penPaintEvent(self, event, item):
# draw item as usual
type(item).paintEvent(item, event)
path = QtGui.QPainterPath()
displaySize = item.size()
w, h = displaySize.width(), displaySize.height()
# draw a squiggle with the pen
path.moveTo(w * .2, h * .2)
path.lineTo(w * .4, h * .8)
path.cubicTo(w * .5, h * .1, w * .7, h * .1, w * .8, h * .8)
painter = QtGui.QPainter(item)
painter.setPen(self.pen)
painter.drawPath(path)
painter.end()
def buttonPaintEvent(self, event):
return self.penPaintEvent(event, self.button)
def displayPaintEvent(self, event):
return self.penPaintEvent(event, self.displayLabel)
class PenParameter(Parameter):
"""
Controls the appearance of a QPen value.
When `saveState` is called, the value is encoded as (color, width, style, capStyle, joinStyle, cosmetic)
============== ========================================================
**Options:**
color pen color, can be any argument accepted by :func:`~pyqtgraph.mkColor` (defaults to black)
width integer width >= 0 (defaults to 1)
style String version of QPenStyle enum, i.e. 'SolidLine' (default), 'DashLine', etc.
capStyle String version of QPenCapStyle enum, i.e. 'SquareCap' (default), 'RoundCap', etc.
joinStyle String version of QPenJoinStyle enum, i.e. 'BevelJoin' (default), 'RoundJoin', etc.
cosmetic Boolean, whether or not the pen is cosmetic (defaults to True)
============== ========================================================
"""
itemClass = PenParameterItem
sigPenChanged = QtCore.Signal(object,object)
def __init__(self, **opts):
self.pen = fn.mkPen()
self.penOptsParam = PenSelectorDialog.mkParam(self.pen)
super().__init__(**opts)
def saveState(self, filter=None):
state = super().saveState(filter)
overrideState = self.penOptsParam.saveState(filter)['children']
state['value'] = tuple(s['value'] for s in overrideState.values())
return state
def _interpretValue(self, v):
return self.mkPen(v)
def setValue(self, value, blockSignal=None):
if not fn.eq(value, self.pen):
value = self.mkPen(value)
PenSelectorDialog.updateParamFromPen(self.penOptsParam, value)
return super().setValue(self.pen, blockSignal)
def applyOptsToPen(self, **opts):
# Transform opts into a value for the current pen
paramNames = set(opts).intersection(self.penOptsParam.names)
# Value should be overridden by opts
with self.treeChangeBlocker():
if 'value' in opts:
pen = self.mkPen(opts.pop('value'))
if not fn.eq(pen, self.pen):
PenSelectorDialog.updateParamFromPen(self.penOptsParam, pen)
penOpts = {}
for kk in paramNames:
penOpts[kk] = opts[kk]
self.penOptsParam[kk] = opts[kk]
return penOpts
def setOpts(self, **opts):
# Transform opts into a value
penOpts = self.applyOptsToPen(**opts)
if penOpts:
self.setValue(self.pen)
return super().setOpts(**opts)
def mkPen(self, *args, **kwargs):
"""Thin wrapper around fn.mkPen which accepts the serialized state from saveState"""
if len(args) == 1 and isinstance(args[0], tuple) and len(args[0]) == len(self.penOptsParam.childs):
opts = dict(zip(self.penOptsParam.names, args[0]))
self.applyOptsToPen(**opts)
args = (self.pen,)
kwargs = {}
return fn.mkPen(*args, **kwargs)