#
# Copyright © 2009-2010 CEA
# Pierre Raybaut
# Licensed under the terms of the CECILL License
# (see guiqwt/__init__.py for details)
# pylint: disable=C0103
"""
guiqwt.styles
-------------
The `styles` module provides set of parameters (DataSet classes) to
configure `plot items` and `plot tools`.
.. seealso::
Module :py:mod:`guiqwt.plot`
Module providing ready-to-use curve and image plotting widgets and
dialog boxes
Module :py:mod:`guiqwt.curve`
Module providing curve-related plot items and plotting widgets
Module :py:mod:`guiqwt.image`
Module providing image-related plot items and plotting widgets
Module :py:mod:`guiqwt.tools`
Module providing the `plot tools`
Reference
~~~~~~~~~
.. autoclass:: CurveParam
:members:
:inherited-members:
.. autoclass:: ErrorBarParam
:members:
:inherited-members:
.. autoclass:: GridParam
:members:
:inherited-members:
.. autoclass:: ImageParam
:members:
:inherited-members:
.. autoclass:: TrImageParam
:members:
:inherited-members:
.. autoclass:: ImageFilterParam
:members:
:inherited-members:
.. autoclass:: HistogramParam
:members:
:inherited-members:
.. autoclass:: Histogram2DParam
:members:
:inherited-members:
.. autoclass:: AxesParam
:members:
:inherited-members:
.. autoclass:: ImageAxesParam
:members:
:inherited-members:
.. autoclass:: LabelParam
:members:
:inherited-members:
.. autoclass:: LegendParam
:members:
:inherited-members:
.. autoclass:: ShapeParam
:members:
:inherited-members:
.. autoclass:: AnnotationParam
:members:
:inherited-members:
.. autoclass:: AxesShapeParam
:members:
:inherited-members:
.. autoclass:: RangeShapeParam
:members:
:inherited-members:
.. autoclass:: MarkerParam
:members:
:inherited-members:
.. autoclass:: FontParam
:members:
:inherited-members:
.. autoclass:: SymbolParam
:members:
:inherited-members:
.. autoclass:: LineStyleParam
:members:
:inherited-members:
.. autoclass:: BrushStyleParam
:members:
:inherited-members:
.. autoclass:: TextStyleParam
:members:
:inherited-members:
"""
import numpy as np
from guidata.qt.QtGui import (QPen, QBrush, QColor, QFont, QFontDialog,
QTransform)
from guidata.qt.QtCore import Qt, QSize, QPointF
from guidata.dataset.datatypes import (DataSet, ObjectItem, BeginGroup,
EndGroup, Obj, DataSetGroup,
BeginTabGroup, EndTabGroup,
GetAttrProp, NotProp)
from guidata.dataset.dataitems import (ChoiceItem, BoolItem, FloatItem, IntItem,
ImageChoiceItem, ColorItem, StringItem,
ButtonItem, FloatArrayItem, TextItem)
from guidata.dataset.qtwidgets import DataSetEditLayout
from guidata.dataset.qtitemwidgets import DataSetWidget
from guidata.utils import update_dataset
# Local imports
from guiqwt.transitional import QwtPlot, QwtPlotCurve, QwtSymbol, QwtPlotMarker
from guiqwt.config import _
from guiqwt.colormap import get_colormap_list, build_icon_from_cmap_name
from guiqwt.signals import SIG_ITEMS_CHANGED
class ItemParameters(object):
"""Class handling QwtPlotItem-like parameters"""
MULTISEL_DATASETS = []
# Customizing tab display order:
ENDING_PARAMETERS = ("CurveParam", "ErrorBarParam",
"ShapeParam", "LabelParam", "LegendParam",
"GridParam", "AxesParam")
def __init__(self, multiselection=False):
self.multiselection = multiselection
self.paramdict = {}
self.items = set()
@classmethod
def register_multiselection(cls, klass, klass_ms):
"""Register a DataSet couple: (DataSet, DataSet_for_MultiSelection)"""
# Inserting element backwards because classes have to be registered
# from children to parent (see 'add' method to fully understand why)
cls.MULTISEL_DATASETS.insert(0, (klass, klass_ms))
def __add(self, key, item, param):
self.paramdict[key] = param
self.items.add(item)
def add(self, key, item, param):
if self.multiselection:
for klass, klass_ms in self.MULTISEL_DATASETS:
if isinstance(param, klass):
title = param.get_title()
if key in self.paramdict and not title.endswith('s'):
title += 's'
param_ms = klass_ms(title=title,
comment=param.get_comment(),
icon=param.get_icon())
update_dataset(param_ms, param)
self.__add(key, item, param_ms)
return
self.__add(key, item, param)
def get(self, key):
from copy import copy
return copy(self.paramdict.get(key))
def update(self, plot):
#FIXME: without the following workaround, ImagePlot object aspect ratio
# is changed when pressing button "Apply"
# (see also guiqwt.image.ImagePlot.edit_axis_parameters)
from guiqwt.image import ImagePlot
if isinstance(plot, ImagePlot):
ratio = plot.get_current_aspect_ratio()
for item in self.items:
item.set_item_parameters(self)
plot.replot()
if isinstance(plot, ImagePlot):
plot.set_aspect_ratio(ratio=ratio)
plot.replot()
plot.emit(SIG_ITEMS_CHANGED, plot)
def edit(self, plot, title, icon):
paramdict = self.paramdict.copy()
ending_parameters = []
for key in self.ENDING_PARAMETERS:
if key in paramdict:
ending_parameters.append(paramdict.pop(key))
parameters = paramdict.values()+ending_parameters
dset = DataSetGroup(parameters, title=title.rstrip('.'), icon=icon)
if dset.edit(parent=plot, apply=lambda dset: self.update(plot)):
self.update(plot)
LINESTYLES = {
"-" : "SolidLine",
"--" : "DashLine",
":" : "DotLine",
"-." : "DashDotLine",
}
COLORS = {
"r" : "red",
"g" : "green",
"b" : "blue",
"c" : "cyan",
"m" : "magenta",
"y" : "yellow",
"k" : "black",
"w" : "white",
"G" : "gray",
}
MARKERS = {
"+" : QwtSymbol.Cross,
"o" : QwtSymbol.Ellipse,
"*" : QwtSymbol.Star1,
"." : QwtSymbol(QwtSymbol.Ellipse, QBrush(Qt.black),
QPen(Qt.black), QSize(3, 3)),
"x" : QwtSymbol.XCross,
"s" : QwtSymbol.Rect,
"d" : QwtSymbol.Diamond,
"^" : QwtSymbol.UTriangle,
"v" : QwtSymbol.DTriangle,
">" : QwtSymbol.RTriangle,
"<" : QwtSymbol.LTriangle,
"h" : QwtSymbol.Star2,
}
MARKERSTYLES = {
None: "NoLine",
"-" : "HLine",
"|" : "VLine",
"+" : "Cross",
}
def style_generator(color_keys="bgrcmykG"):
"""Cycling through curve styles"""
while True:
for linestyle in sorted(LINESTYLES.keys()):
for color in color_keys:
yield color+linestyle
def update_style_attr(style, param):
"""Parse a MATLAB-like style string and
update the color, linestyle, marker attributes of the param
object
"""
for marker in MARKERS.keys():
if marker in style:
param.symbol.update_param(MARKERS[marker])
break
else:
param.symbol.update_param(QwtSymbol.NoSymbol)
for linestyle in LINESTYLES.keys():
if linestyle in style:
param.line.style = LINESTYLES[linestyle]
break
else:
param.line.style = "NoPen"
for color in COLORS.keys():
if color in style:
param.line.color = COLORS[color]
param.symbol.facecolor = COLORS[color]
param.symbol.edgecolor = COLORS[color]
break
def build_reverse_map(lst, obj):
dict = {}
for idx, _name, _icon in lst:
val = getattr(obj, idx)
dict[val] = idx
return dict
LINESTYLE_CHOICES = [("SolidLine", _("Solid line"), "solid.png"),
("DashLine", _("Dashed line"), "dash.png"),
("DotLine", _("Dotted line"), "dot.png"),
("DashDotLine", _("Dash-dot line"), "dashdot.png"),
("DashDotDotLine", _("Dash-dot-dot line"), "dashdotdot.png"),
("NoPen", _("No line"), "none.png"),
]
MARKER_CHOICES = [("Cross", _("Cross"), "cross.png"),
("Ellipse", _("Ellipse"), "ellipse.png"),
("Star1", _("Star"), "star.png"),
("XCross", _("X-Cross"), "xcross.png"),
("Rect", _("Square"), "square.png"),
("Diamond", _("Diamond"), "diamond.png"),
("UTriangle", _("Triangle"), "triangle_u.png"),
("DTriangle", _("Triangle"), "triangle_d.png"),
("RTriangle", _("Triangle"), "triangle_r.png"),
("LTriangle", _("Triangle"), "triangle_l.png"),
("Star2", _("Hexagon"), "hexagon.png"),
("NoSymbol", _("No symbol"), "none.png"),
]
CURVESTYLE_CHOICES = [("Lines", _("Lines"), "lines.png"),
("Sticks", _("Sticks"), "sticks.png"),
("Steps", _("Steps"), "steps.png"),
("Dots", _("Dots"), "dots.png"),
("NoCurve", _("No curve"), "none.png")
]
CURVETYPE_CHOICES = [("Yfx", _("Draws y as a function of x"), "yfx.png"),
("Xfy", _("Draws x as a function of y"), "xfy.png")]
BRUSHSTYLE_CHOICES = [
("NoBrush", _("No brush pattern"), "nobrush.png"),
("SolidPattern", _("Uniform color"), "solidpattern.png"),
("Dense1Pattern", _("Extremely dense brush pattern"), "dense1pattern.png"),
("Dense2Pattern", _("Very dense brush pattern"), "dense2pattern.png"),
("Dense3Pattern", _("Somewhat dense brush pattern"), "dense3pattern.png"),
("Dense4Pattern", _("Half dense brush pattern"), "dense4pattern.png"),
("Dense5Pattern", _("Somewhat sparse brush pattern"), "dense5pattern.png"),
("Dense6Pattern", _("Very sparse brush pattern"), "dense6pattern.png"),
("Dense7Pattern", _("Extremely sparse brush pattern"), "dense7pattern.png"),
("HorPattern", _("Horizontal lines"), "horpattern.png"),
("VerPattern", _("Vertical lines"), "verpattern.png"),
("CrossPattern", _("Crossing horizontal and vertical lines"),
"crosspattern.png"),
("BDiagPattern", _("Backward diagonal lines"), "bdiagpattern.png"),
("FDiagPattern", _("Forward diagonal lines"), "fdiagpattern.png"),
("DiagCrossPattern", _("Crossing diagonal lines"), "diagcrosspattern.png"),
# ("LinearGradientPattern", _("Linear gradient (set using a dedicated QBrush constructor)"), "none.png"),
# ("ConicalGradientPattern", _("Conical gradient (set using a dedicated QBrush constructor)"), "none.png"),
# ("RadialGradientPattern", _("Radial gradient (set using a dedicated QBrush constructor)"), "none.png"),
# ("TexturePattern", _("Custom pattern (see QBrush::setTexture())"), "none.png"),
]
MARKERSTYLE_CHOICES = [("NoLine", _("None"), "none.png"),
("HLine", _("Horizontal"), "horiz_marker.png"),
("VLine", _("Vertical"), "vert_marker.png"),
("Cross", _("Cross"), "cross_marker.png"),
]
MARKER_NAME = build_reverse_map(MARKER_CHOICES, QwtSymbol)
CURVESTYLE_NAME = build_reverse_map(CURVESTYLE_CHOICES, QwtPlotCurve)
CURVETYPE_NAME = build_reverse_map(CURVETYPE_CHOICES, QwtPlotCurve)
LINESTYLE_NAME = build_reverse_map(LINESTYLE_CHOICES, Qt)
BRUSHSTYLE_NAME = build_reverse_map(BRUSHSTYLE_CHOICES, Qt)
MARKERSTYLE_NAME = build_reverse_map(MARKERSTYLE_CHOICES, QwtPlotMarker)
# ===================================================
# Common font parameters
# ===================================================
def _font_selection(param, item, value, parent):
font = param.build_font()
result, valid = QFontDialog.getFont(font, parent)
if valid:
param.update_param( result )
class FontParam(DataSet):
[docs] family = StringItem(_("Family"), default="default")
_choose = ButtonItem(_("Choose font"), _font_selection,
default=None).set_pos(col=1)
size = IntItem(_("Size in point"), default=12)
bold = BoolItem(_("Bold"), default=False).set_pos(col=1)
italic = BoolItem(_("Italic"), default=False).set_pos(col=2)
def update_param(self, font):
self.family = str(font.family())
self.size = font.pointSize()
self.bold = bool(font.bold())
self.italic = bool(font.italic())
def build_font(self):
font = QFont(self.family)
font.setPointSize( self.size )
font.setBold( self.bold )
font.setItalic( self.italic )
return font
class FontItemWidget(DataSetWidget):
klass = FontParam
class FontItem(ObjectItem):
"""Item holding a LineStyleParam"""
klass = FontParam
DataSetEditLayout.register(FontItem, FontItemWidget)
# ===================================================
# Common Qwt symbol parameters
# ===================================================
class SymbolParam(DataSet):
[docs] marker = ImageChoiceItem(_("Style"), MARKER_CHOICES,
default="NoSymbol")
size = IntItem(_("Size"), default=9)
edgecolor = ColorItem(_("Border"), default="gray")
facecolor = ColorItem(_("Background color"), default="yellow")
alpha = FloatItem(_("Background alpha"), default=1., min=0, max=1)
def update_param(self, symb):
if not isinstance(symb, QwtSymbol):
# check if this is still needed
#raise RuntimeError
assert isinstance(symb, QwtSymbol.Style)
self.marker = MARKER_NAME[symb]
return
self.marker = MARKER_NAME[symb.style()]
self.size = symb.size().width()
self.edgecolor = str(symb.pen().color().name())
self.facecolor = str(symb.brush().color().name())
def build_symbol(self):
marker_type = getattr(QwtSymbol, self.marker)
color = QColor(self.facecolor)
color.setAlphaF(self.alpha)
marker = QwtSymbol(marker_type, QBrush(color),
QPen(QColor(self.edgecolor)),
QSize(self.size, self.size))
return marker
def update_symbol(self, obj):
obj.setSymbol(self.build_symbol())
class SymbolItemWidget(DataSetWidget):
klass = SymbolParam
class SymbolItem(ObjectItem):
"""Item holding a SymbolParam"""
klass = SymbolParam
DataSetEditLayout.register(SymbolItem, SymbolItemWidget)
# ===================================================
# Common line style parameters
# ===================================================
class LineStyleParam(DataSet):
[docs] style = ImageChoiceItem(_("Style"), LINESTYLE_CHOICES, default="SolidLine")
color = ColorItem(_("Color"), default="black")
width = FloatItem(_("Width"), default=1., min=0)
def update_param(self, pen):
self.width = pen.widthF()
self.color = str(pen.color().name())
self.style = LINESTYLE_NAME[pen.style()]
def build_pen(self):
linecolor = QColor(self.color)
style = getattr(Qt, self.style)
pen = QPen(linecolor, self.width, style)
return pen
def set_style_from_matlab(self, linestyle):
[docs] """Eventually convert MATLAB-like linestyle into Qt linestyle"""
linestyle = LINESTYLES.get(linestyle, linestyle) # MATLAB-style
if linestyle == '': # MATLAB-style
linestyle = 'NoPen'
self.style = linestyle
class LineStyleItemWidget(DataSetWidget):
klass = LineStyleParam
class LineStyleItem(ObjectItem):
"""Item holding a LineStyleParam"""
klass = LineStyleParam
DataSetEditLayout.register(LineStyleItem, LineStyleItemWidget)
# ===================================================
# Common brush style parameters
# ===================================================
class BrushStyleParam(DataSet):
[docs] style = ImageChoiceItem(_("Style"), BRUSHSTYLE_CHOICES,
default="SolidPattern")
color = ColorItem(_("Color"), default="black")
alpha = FloatItem(_("Alpha"), default=1.0)
angle = FloatItem(_("Angle"), default=0., min=0)
sx = FloatItem(_("sx"), default=1., min=0)
sy = FloatItem(_("sy"), default=1., min=0)
def update_param(self, brush):
from math import pi, sqrt, atan2
tr = brush.transform()
pt = tr.map( QPointF(1.0, 0.0) )
self.sx = sqrt(pt.x()**2+pt.y()**2)
self.angle = 180*atan2(pt.y(), pt.x())/pi
pt = tr.map( QPointF(0.0, 1.0) )
self.sy = sqrt(pt.x()**2+pt.y()**2)
col = brush.color()
self.color = str(col.name())
self.alpha = col.alphaF()
self.style = BRUSHSTYLE_NAME[brush.style()]
def build_brush(self):
color = QColor(self.color)
color.setAlphaF(self.alpha)
brush = QBrush(color, getattr(Qt,self.style))
tr = QTransform()
tr = tr.scale(self.sx, self.sy)
tr = tr.rotate(self.angle)
brush.setTransform(tr)
return brush
class BrushStyleItemWidget(DataSetWidget):
klass = BrushStyleParam
class BrushStyleItem(ObjectItem):
"""Item holding a LineStyleParam"""
klass = BrushStyleParam
DataSetEditLayout.register(BrushStyleItem, BrushStyleItemWidget)
# ===================================================
# QwtText parameters
# ===================================================
class TextStyleParam(DataSet):
[docs] font = FontItem(_("Font"))
textcolor = ColorItem(_("Text color"), default="blue")
background_color = ColorItem(_("Background color"), default="white")
background_alpha = FloatItem(_("Background alpha"),
default=0.5, min=0, max=1)
def update_param(self, obj):
[docs] """obj: QwtText instance"""
self.font.update_param( obj.font() )
self.textcolor = obj.color().name()
color = obj.backgroundBrush().color()
self.background_color = color.name()
self.background_alpha = color.alphaF()
def update_text(self, obj):
[docs] """obj: QwtText instance"""
obj.setColor( QColor(self.textcolor) )
color = QColor(self.background_color)
color.setAlphaF(self.background_alpha)
obj.setBackgroundBrush( QBrush(color) )
font = self.font.build_font()
obj.setFont(font)
class TextStyleItemWidget(DataSetWidget):
klass = TextStyleParam
class TextStyleItem(ObjectItem):
"""Item holding a TextStyleParam"""
klass = TextStyleParam
DataSetEditLayout.register(TextStyleItem, TextStyleItemWidget)
# ===================================================
# Grid parameters
# ===================================================
class GridParam(DataSet):
[docs] background = ColorItem(_("Background color"), default="white")
maj = BeginGroup(_("Major grid") )
maj_xenabled = BoolItem(_("X Axis"), default=True)
maj_yenabled = BoolItem(_("Y Axis"), default=True).set_pos(col=1)
maj_line = LineStyleItem(_("Line"))
_maj = EndGroup("end group")
min = BeginGroup(_("Minor grid"))
min_xenabled = BoolItem(_("X Axis"), default=False)
min_yenabled = BoolItem(_("Y Axis"), default=False).set_pos(col=1)
min_line = LineStyleItem(_("Line"))
_min = EndGroup("fin groupe")
def update_param(self, grid):
plot = grid.plot()
if plot is not None:
self.background = str(plot.canvasBackground().name())
self.maj_xenabled = grid.xEnabled()
self.maj_yenabled = grid.yEnabled()
self.maj_line.update_param( grid.majPen() )
self.min_xenabled = grid.xMinEnabled()
self.min_yenabled = grid.yMinEnabled()
self.min_line.update_param( grid.minPen() )
def update_grid(self, grid):
plot = grid.plot()
if plot is not None:
plot.setCanvasBackground( QColor(self.background) )
grid.enableX(self.maj_xenabled)
grid.enableY(self.maj_yenabled)
grid.setPen( self.maj_line.build_pen() )
grid.enableXMin(self.min_xenabled)
grid.enableYMin(self.min_yenabled)
grid.setMinPen( self.min_line.build_pen() )
grid.setTitle(self.get_title())
# ===================================================
# Axes style parameters
# ===================================================
class AxeStyleParam(DataSet):
title = StringItem(_("Title"), default=u"")
unit = StringItem(_("Unit"), default=u"")
color = ColorItem(_("Color"), default="black").set_pos(col=1)
title_font = FontItem(_("Title font"))
ticks_font = FontItem(_("Values font"))
# ===================================================
# Axes parameters
# ===================================================
class AxisParam(DataSet):
scale = ChoiceItem(_("Scale"),
[("lin", _("linear")), ("log", _("logarithmic"))],
default="lin")
vmin = FloatItem("Min", help=_("Lower axis limit"))
vmax = FloatItem("Max", help=_("Upper axis limit"))
def update_param(self, plot, axis_id):
self.scale = plot.get_axis_scale(axis_id)
axis = plot.axisScaleDiv(axis_id)
self.vmin = axis.lowerBound()
self.vmax = axis.upperBound()
def update_axis(self, plot, axis_id):
plot.enableAxis(axis_id, True)
plot.set_axis_scale(axis_id, self.scale, autoscale=False)
plot.setAxisScale(axis_id, self.vmin, self.vmax)
plot.disable_unused_axes()
class AxisItemWidget(DataSetWidget):
klass = AxisParam
class AxisItem(ObjectItem):
klass = AxisParam
DataSetEditLayout.register(AxisItem, AxisItemWidget)
class AxesParam(DataSet):
[docs] xaxis_id = ChoiceItem(_("X-axis position"),
[(QwtPlot.xBottom, _("bottom")),
(QwtPlot.xTop, _("top"))],
default=QwtPlot.xBottom)
xaxis = AxisItem(_("X Axis"))
yaxis_id = ChoiceItem(_("Y-axis position"),
[(QwtPlot.yLeft, _("left")),
(QwtPlot.yRight, _("right"))],
default=QwtPlot.yLeft)
yaxis = AxisItem(_("Y Axis"))
def update_param(self, item):
plot = item.plot()
self.xaxis_id = item.xAxis()
self.xaxis.update_param(plot, self.xaxis_id)
self.yaxis_id = item.yAxis()
self.yaxis.update_param(plot, self.yaxis_id)
def update_axes(self, item):
plot = item.plot()
plot.grid.setAxis(self.xaxis_id, self.yaxis_id)
item.setXAxis(self.xaxis_id)
self.xaxis.update_axis(plot, self.xaxis_id)
item.setYAxis(self.yaxis_id)
self.yaxis.update_axis(plot, self.yaxis_id)
class ImageAxesParam(DataSet):
[docs] xparams = BeginGroup(_("X Axis") )
xmin = FloatItem("x|min", help=_("Lower x-axis limit"))
xmax = FloatItem("x|max", help=_("Upper x-axis limit"))
_xparams = EndGroup("end X")
yparams = BeginGroup(_("Y Axis") )
ymin = FloatItem("y|min", help=_("Lower y-axis limit"))
ymax = FloatItem("y|max", help=_("Upper y-axis limit"))
_yparams = EndGroup("end Y")
zparams = BeginGroup(_("Z Axis") )
zmin = FloatItem("z|min", help=_("Lower z-axis limit"))
zmax = FloatItem("z|max", help=_("Upper z-axis limit"))
_zparams = EndGroup("end Z")
def update_param(self, item):
plot = item.plot()
xaxis = plot.axisScaleDiv(item.xAxis())
self.xmin = xaxis.lowerBound()
self.xmax = xaxis.upperBound()
yaxis = plot.axisScaleDiv(item.yAxis())
self.ymin = yaxis.lowerBound()
self.ymax = yaxis.upperBound()
self.zmin, self.zmax = item.min, item.max
def update_axes(self, item):
plot = item.plot()
plot.set_plot_limits(self.xmin, self.xmax, self.ymin, self.ymax)
item.set_lut_range([self.zmin, self.zmax])
plot.update_colormap_axis(item)
# ===================================================
# Label parameters
# ===================================================
class LabelParam(DataSet):
[docs] _multiselection = False
_legend = False
_no_contents = True
label = StringItem(_("Title"), default="") \
.set_prop("display", hide=GetAttrProp("_multiselection"))
_styles = BeginTabGroup("Styles")
#-------------------------------------------------------------- Contents tab
___cont = BeginGroup(_("Contents")).set_prop("display", icon="label.png",
hide=GetAttrProp("_no_contents"))
contents = TextItem("").set_prop("display",
hide=GetAttrProp("_no_contents"))
___econt = EndGroup(_("Contents")).set_prop("display",
hide=GetAttrProp("_no_contents"))
#---------------------------------------------------------------- Symbol tab
symbol = SymbolItem(_("Symbol")).set_prop("display", icon="diamond.png",
hide=GetAttrProp("_legend"))
#---------------------------------------------------------------- Border tab
border = LineStyleItem(_("Border"), default=Obj(color="#cbcbcb"),
help=_("set width to 0 to disable")
).set_prop("display", icon="dashdot.png")
#------------------------------------------------------------------ Text tab
___text = BeginGroup(_("Text")).set_prop("display", icon="font.png")
font = FontItem(_("Text font"))
color = ColorItem(_("Text color"), default="#000000")
bgcolor = ColorItem(_("Background color"), default="#ffffff")
bgalpha = FloatItem(_("Background transparency"),
min=0.0, max=1.0, default=0.8)
___etext = EndGroup(_("Text"))
#-------------------------------------------------------------- Position tab
___position = BeginGroup(_("Position")).set_prop("display", icon="move.png")
_begin_anchor = BeginGroup(_("Position relative to anchor")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
anchor = ChoiceItem(_("Corner"),
[("TL" , _("Top left") ),
("TR" , _("Top right") ),
("BL" , _("Bottom left") ),
("BR" , _("Bottom right") ),
("L" , _("Left") ),
("R" , _("Right") ),
("T" , _("Top") ),
("B" , _("Bottom") ),
("C" , _("Center") ),], default="TL",
help=_("Label position relative to anchor point")) \
.set_prop("display",
hide=GetAttrProp("_multiselection"))
xc = IntItem(_(u"ΔX"), default=5,
help=_("Horizontal offset (pixels) relative to anchor point"))\
.set_prop("display", hide=GetAttrProp("_multiselection"))
yc = IntItem(_(u"ΔY"), default=5,
help=_("Vertical offset (pixels) relative to anchor point")
).set_pos(col=1).set_prop("display",
hide=GetAttrProp("_multiselection"))
_end_anchor = EndGroup(_("Anchor")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
_begin_anchorpos = BeginGroup(_("Anchor position")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
_abspos_prop = GetAttrProp("abspos")
abspos = BoolItem(text=_("Attach to canvas"), label=_("Anchor"),
default=True
).set_prop("display", store=_abspos_prop) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
xg = FloatItem(_("X"), default=0.0,
help=_("X-axis position in canvas coordinates")
).set_prop("display", active=NotProp(_abspos_prop)) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
yg = FloatItem(_("Y"), default=0.0,
help=_("Y-axis position in canvas coordinates")
).set_pos(col=1) \
.set_prop("display", active=NotProp(_abspos_prop)) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
move_anchor = ChoiceItem(_(u"Interact"),
((True, _("moving object changes anchor position")),
(False, _("moving object changes label position"))),
default=True
).set_prop("display", active=NotProp(_abspos_prop)) \
.set_prop("display",
hide=GetAttrProp("_multiselection"))
absg = ChoiceItem(_("Position"),
[("TL", _("Top left") ),
("TR", _("Top right") ),
("BL", _("Bottom left") ),
("BR", _("Bottom right") ),
("L" , _("Left") ),
("R" , _("Right") ),
("T" , _("Top") ),
("B" , _("Bottom") ),
("C" , _("Center") ),], default="TL",
help=_("Absolute position on canvas")
).set_prop("display", active=_abspos_prop) \
.set_prop("display",
hide=GetAttrProp("_multiselection"))
_end_anchorpos = EndGroup(_("Anchor position")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
___eposition = EndGroup(_("Position"))
#----------------------------------------------------------------------- End
_endstyles = EndTabGroup("Styles")
def update_param(self, obj):
# The following is necessary only for shape labels:
# when shape is just created (and not yet moved), we need to update
# these attributes
if self.abspos:
self.absg = obj.G
else:
self.xg, self.yg = obj.G
self.xc, self.yc = obj.C
def update_label(self, obj):
if not self._multiselection:
if self.abspos:
obj.G = self.absg
else:
obj.G = (self.xg, self.yg)
obj.C = self.xc, self.yc
obj.anchor = self.anchor
obj.move_anchor = self.move_anchor
obj.setTitle(self.label)
obj.marker = self.symbol.build_symbol()
obj.border_pen = self.border.build_pen()
obj.set_text_style(self.font.build_font(), self.color)
color = QColor(self.bgcolor)
color.setAlphaF(self.bgalpha)
obj.bg_brush = QBrush(color)
class LabelParam_MS(LabelParam):
_multiselection = True
ItemParameters.register_multiselection(LabelParam, LabelParam_MS)
class LegendParam(LabelParam):
[docs] _legend = True
label = StringItem(_("Title"), default="").set_prop("display", hide=True)
def update_label(self, obj):
super(LegendParam, self).update_label(obj)
if not self._multiselection:
obj.setTitle(self.get_title())
class LegendParam_MS(LegendParam):
_multiselection = True
ItemParameters.register_multiselection(LegendParam, LegendParam_MS)
class LabelParamWithContents(LabelParam):
_no_contents = False
def __init__(self, title=None, comment=None, icon=''):
self.plain_text = None
super(LabelParamWithContents, self).__init__(title, comment, icon)
def update_param(self, obj):
super(LabelParamWithContents, self).update_param(obj)
self.contents = self.plain_text = obj.get_plain_text()
def update_label(self, obj):
super(LabelParamWithContents, self).update_label(obj)
if self.plain_text is not None and self.contents != self.plain_text:
text = self.contents.replace('\n', '<br>')
obj.set_text(text)
class LabelParamWithContents_MS(LabelParamWithContents):
_multiselection = True
ItemParameters.register_multiselection(LabelParamWithContents,
LabelParamWithContents_MS)
# ===================================================
# Curve parameters
# ===================================================
class CurveParam(DataSet):
[docs] _multiselection = False
label = StringItem(_("Title"), default="").set_prop("display",
hide=GetAttrProp("_multiselection"))
line = LineStyleItem(_("Line"))
symbol = SymbolItem(_("Symbol"))
shade = FloatItem(_("Shadow"), default=0, min=0, max=1)
fitted = BoolItem(_("Fit curve to data"), _("Fitting"), default=False)
curvestyle = ImageChoiceItem(_("Curve style"), CURVESTYLE_CHOICES,
default="Lines")
curvetype = ImageChoiceItem(_("Curve type"), CURVETYPE_CHOICES,
default="Yfx")
baseline = FloatItem(_("Baseline"), default=0.)
def update_param(self, curve):
self.symbol.update_param(curve.symbol())
self.line.update_param(curve.pen())
self.curvestyle = CURVESTYLE_NAME[curve.style()]
self.curvetype = CURVETYPE_NAME[curve.curveType()]
self.baseline = curve.baseline()
def update_curve(self, curve):
if not self._multiselection:
# Non common parameters
curve.setTitle(self.label)
curve.setPen(self.line.build_pen())
# Brush
linecolor = QColor(self.line.color)
linecolor.setAlphaF(self.shade)
brush = QBrush(linecolor)
if not self.shade:
brush.setStyle(Qt.NoBrush)
curve.setBrush(brush)
# Symbol
self.symbol.update_symbol( curve )
# CurveAttribute
curve.setCurveAttribute(QwtPlotCurve.Fitted, self.fitted)
# Curve style, type and baseline
curve.setStyle(getattr(QwtPlotCurve, self.curvestyle))
curve.setCurveType(getattr(QwtPlotCurve, self.curvetype))
curve.setBaseline(self.baseline)
class CurveParam_MS(CurveParam):
_multiselection = True
ItemParameters.register_multiselection(CurveParam, CurveParam_MS)
# ===================================================
# ErrorBar Curve parameters
# ===================================================
class ErrorBarParam(DataSet):
[docs] mode = ChoiceItem(_("Display"), default=0,
choices=[_("error bars with caps (x, y)"),
_("error area (y)")],
help=_("Note: only y-axis error bars are shown in "
"error area mode\n(width and cap parameters "
"will also be ignored)"))
color = ColorItem(_("Color"), default="darkred")
alpha = FloatItem(_("Alpha"), default=.9, min=0, max=1,
help=_("Error bar transparency"))
width = FloatItem(_("Width"), default=1.0, min=1)
cap = IntItem(_("Cap"), default=4, min=0)
ontop = BoolItem(_("set to foreground"), _("Visibility"), default=False)
def update_param(self, curve):
color = curve.errorPen.pen().color()
self.color = str(color.name())
self.alpha = color.alphaF()
self.width = curve.errorPen.widthF()
self.cap = curve.errorCap
self.ontop = curve.errorOnTop
def update_curve(self, curve):
color = QColor(self.color)
color.setAlphaF(self.alpha)
curve.errorPen = QPen(color, self.width)
curve.errorBrush = QBrush(color)
curve.errorCap = self.cap
curve.errorOnTop = self.ontop
# ===================================================
# Image parameters
# ===================================================
def _create_choices():
choices = []
for cmap_name in get_colormap_list():
choices.append((cmap_name, cmap_name, build_icon_from_cmap_name))
return choices
class BaseImageParam(DataSet):
_multiselection = False
label = StringItem(_("Image title"), default=_("Image")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
alpha_mask = BoolItem(_("Use image level as alpha"), _("Alpha channel"),
default=False)
alpha = FloatItem(_("Global alpha"), default=1.0, min=0, max=1,
help=_("Global alpha value"))
_hide_colormap = False
colormap = ImageChoiceItem(_("Colormap"), _create_choices(), default="jet"
).set_prop("display",
hide=GetAttrProp("_hide_colormap"))
interpolation = ChoiceItem(_("Interpolation"),
[(0, _("None (nearest pixel)")),
(1, _("Linear interpolation")),
(2, _("2x2 antialiasing filter")),
(3, _("3x3 antialiasing filter")),
(5, _("5x5 antialiasing filter"))],
default=0, help=_("Image interpolation type"))
_formats = BeginGroup(_("Statistics string formatting"))
xformat = StringItem(_("X-Axis"), default=r'%.1f')
yformat = StringItem(_("Y-Axis"), default=r'%.1f')
zformat = StringItem(_("Z-Axis"), default=r'%.1f')
_end_formats = EndGroup(_("Statistics string formatting"))
def update_param(self, image):
self.label = unicode(image.title().text())
self.colormap = image.get_color_map_name()
interpolation = image.get_interpolation()
mode = interpolation[0]
from guiqwt.image import INTERP_NEAREST, INTERP_LINEAR
if mode == INTERP_NEAREST:
self.interpolation = 0
elif mode == INTERP_LINEAR:
self.interpolation = 1
else:
size = interpolation[1].shape[0]
self.interpolation = size
def update_image(self, image):
image.setTitle(self.label)
image.set_color_map(self.colormap)
size = self.interpolation
from guiqwt.image import INTERP_NEAREST, INTERP_LINEAR, INTERP_AA
if size == 0:
mode = INTERP_NEAREST
elif size == 1:
mode = INTERP_LINEAR
else:
mode = INTERP_AA
image.set_interpolation(mode, size)
class QuadGridParam(DataSet):
_multiselection = False
label = StringItem(_("Image title"), default=_("Image")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
alpha_mask = BoolItem(_("Use image level as alpha"), _("Alpha channel"),
default=False)
alpha = FloatItem(_("Global alpha"), default=1.0, min=0, max=1,
help=_("Global alpha value"))
_hide_colormap = False
colormap = ImageChoiceItem(_("Colormap"), _create_choices(), default="jet"
).set_prop("display",
hide=GetAttrProp("_hide_colormap"))
interpolation = ChoiceItem(_("Interpolation"),
[ (0, _("Quadrangle interpolation")),
(1, _("Flat")),
],
default=0,
help=_("Image interpolation type, "
"Flat mode use fixed u,v "
"interpolation parameters"))
uflat = FloatItem(_("Fixed U interpolation parameter"),
default=0.5,min=0.,max=1., help=_("For flat mode only"))
vflat = FloatItem(_("Fixed V interpolation parameter"),
default=0.5,min=0.,max=1., help=_("For flat mode only"))
grid = BoolItem(_("Show grid"), default=False)
gridcolor = ColorItem(_("Grid lines color"), default="black")
def update_param(self, image):
self.label = unicode(image.title().text())
self.colormap = image.get_color_map_name()
interp, uflat, vflat = image.interpolate
self.interpolation = interp
self.uflat = uflat
self.vflat = vflat
self.grid = image.grid
def update_image(self, image):
image.setTitle(self.label)
image.set_color_map(self.colormap)
image.interpolate = (self.interpolation,self.uflat,self.vflat)
image.grid = self.grid
# TODO : gridcolor
class RawImageParam(BaseImageParam):
_hide_background = False
background = ColorItem(_("Background color"), default="#000000"
).set_prop("display",
hide=GetAttrProp("_hide_background"))
def update_param(self, image):
super(RawImageParam, self).update_param(image)
self.background = str(QColor(image.bg_qcolor).name())
def update_image(self, image):
super(RawImageParam, self).update_image(image)
image.set_background_color(self.background)
class RawImageParam_MS(RawImageParam):
_multiselection = True
ItemParameters.register_multiselection(RawImageParam, RawImageParam_MS)
class XYImageParam(RawImageParam):
pass
class XYImageParam_MS(XYImageParam):
_multiselection = True
ItemParameters.register_multiselection(XYImageParam, XYImageParam_MS)
class ImageParam(RawImageParam):
[docs] _xdata = BeginGroup(_("Image placement along X-axis"))
xmin = FloatItem(_("x|min"), default=None)
xmax = FloatItem(_("x|max"), default=None)
_end_xdata = EndGroup(_("Image placement along X-axis"))
_ydata = BeginGroup(_("Image placement along Y-axis"))
ymin = FloatItem(_("y|min"), default=None)
ymax = FloatItem(_("y|max"), default=None)
_end_ydata = EndGroup(_("Image placement along Y-axis"))
def update_param(self, image):
super(ImageParam, self).update_param(image)
self.xmin = image.xmin
if self.xmin is None:
self.xmin = 0.
self.ymin = image.ymin
if self.ymin is None:
self.ymin = 0.
if image.is_empty():
shape = (0, 0)
else:
shape = image.data.shape
self.xmax = image.xmax
if self.xmax is None:
self.xmax = float(shape[1])
self.ymax = image.ymax
if self.ymax is None:
self.ymax = float(shape[0])
def update_image(self, image):
super(ImageParam, self).update_image(image)
image.xmin = self.xmin
image.xmax = self.xmax
image.ymin = self.ymin
image.ymax = self.ymax
image.update_bounds()
image.update_border()
class ImageParam_MS(ImageParam):
_multiselection = True
ItemParameters.register_multiselection(ImageParam, ImageParam_MS)
class RGBImageParam(ImageParam):
_hide_background = True
_hide_colormap = True
def update_image(self, image):
super(RGBImageParam, self).update_image(image)
image.recompute_alpha_channel()
class RGBImageParam_MS(RGBImageParam):
_multiselection = True
ItemParameters.register_multiselection(RGBImageParam, RGBImageParam_MS)
class MaskedImageParam(ImageParam):
g_mask = BeginGroup(_("Mask"))
filling_value = FloatItem(_("Filling value"))
show_mask = BoolItem(_("Show image mask"), default=False)
alpha_masked = FloatItem(_("Masked area alpha"),
default=.7, min=0, max=1)
alpha_unmasked = FloatItem(_("Unmasked area alpha"),
default=0., min=0, max=1)
_g_mask = EndGroup(_("Mask"))
def update_image(self, image):
super(MaskedImageParam, self).update_image(image)
image.update_mask()
class MaskedImageParam_MS(MaskedImageParam):
_multiselection = True
ItemParameters.register_multiselection(MaskedImageParam, MaskedImageParam_MS)
class ImageFilterParam(BaseImageParam):
[docs] label = StringItem(_("Title"), default=_("Filter"))
g1 = BeginGroup(_("Bounds"))
xmin = FloatItem(_("x|min"))
xmax = FloatItem(_("x|max"))
ymin = FloatItem(_("y|min"))
ymax = FloatItem(_("y|max"))
_g1 = EndGroup("sub-group")
use_source_cmap = BoolItem(_("Use image colormap and level"),
_("Color map"), default=True)
def update_param(self, obj):
self.xmin, self.ymin, self.xmax, self.ymax = obj.border_rect.get_rect()
self.use_source_cmap = obj.use_source_cmap
super(ImageFilterParam,self).update_param(obj)
def update_imagefilter(self, imagefilter):
m, M = imagefilter.get_lut_range()
set_range = False
if not self.use_source_cmap and imagefilter.use_source_cmap:
set_range = True
imagefilter.use_source_cmap = self.use_source_cmap
if set_range:
imagefilter.set_lut_range([m, M])
self.update_image(imagefilter)
imagefilter.border_rect.set_rect(self.xmin, self.ymin,
self.xmax, self.ymax)
class TrImageParam(RawImageParam):
[docs] _crop = BeginGroup(_("Crop")
).set_prop("display", hide=GetAttrProp("_multiselection"))
crop_left = IntItem(_("Left"), default=0)
crop_right = IntItem(_("Right"), default=0)
crop_top = IntItem(_("Top"), default=0)
crop_bottom = IntItem(_("Bottom"), default=0)
_end_crop = EndGroup(_("Cropping")
).set_prop("display", hide=GetAttrProp("_multiselection"))
_ps = BeginGroup(_("Pixel size")
).set_prop("display", hide=GetAttrProp("_multiselection"))
dx = FloatItem(_("Width (dx)"), default=1.0)
dy = FloatItem(_("Height (dy)"), default=1.0)
_end_ps = EndGroup(_("Pixel size")
).set_prop("display", hide=GetAttrProp("_multiselection"))
_pos = BeginGroup(_("Translate, rotate and flip"))
pos_x0 = FloatItem(_("x<sub>CENTER</sub>"), default=0.0
).set_prop("display", hide=GetAttrProp("_multiselection"))
hflip = BoolItem(_("Flip horizontally"), default=False
).set_prop("display", col=1)
pos_y0 = FloatItem(_("y<sub>CENTER</sub>"), default=0.0
).set_prop("display", hide=GetAttrProp("_multiselection"))
vflip = BoolItem(_("Flip vertically"), default=False
).set_prop("display", col=1)
pos_angle = FloatItem(_("θ (°)"), default=0.0).set_prop("display", col=0)
_end_pos = EndGroup(_("Translate, rotate and flip"))
def update_param(self, image):
super(TrImageParam, self).update_param(image)
# we don't get crop info from the image because
# its not easy to extract from the transform
# and TrImageItem keeps it's crop information
# directly in this DataSet
def update_image(self, image):
RawImageParam.update_image(self, image)
image.set_transform(*self.get_transform())
def get_transform(self):
return (self.pos_x0, self.pos_y0, self.pos_angle*np.pi/180,
self.dx, self.dy, self.hflip, self.vflip)
def set_transform(self, x0, y0, angle, dx=1.0, dy=1.0,
hflip=False, vflip=False):
self.pos_x0 = x0
self.pos_y0 = y0
self.pos_angle = angle*180/np.pi
self.dx = dx
self.dy = dy
self.hflip = hflip
self.vflip = vflip
def set_crop(self, left, top, right, bottom):
self.crop_left = left
self.crop_right = right
self.crop_top = top
self.crop_bottom = bottom
def get_crop(self):
return (self.crop_left, self.crop_top,
self.crop_right, self.crop_bottom)
class TrImageParam_MS(TrImageParam):
_multiselection = True
ItemParameters.register_multiselection(TrImageParam, TrImageParam_MS)
# ===================================================
# Histogram parameters
# ===================================================
class HistogramParam(DataSet):
[docs] n_bins = IntItem(_("Bins"), default=100, min=1, help=_("Number of bins"))
logscale = BoolItem(_("logarithmic"), _("Y-axis scale"), default=False)
def update_param(self, obj):
self.n_bins = obj.get_bins()
self.logscale = obj.get_logscale()
def update_hist(self, hist):
hist.set_bins(self.n_bins)
hist.set_logscale(self.logscale)
# ===================================================
# Histogram 2D parameters
# ===================================================
class Histogram2DParam(BaseImageParam):
[docs] """Histogram"""
_multiselection = False
label = StringItem(_("Title"), default=_("Histogram")) \
.set_prop("display", hide=GetAttrProp("_multiselection"))
nx_bins = IntItem(_("X-axis bins"), default=100, min=1,
help=_("Number of bins along x-axis"))
ny_bins = IntItem(_("Y-axis bins"), default=100, min=1,
help=_("Number of bins along y-axis"))
logscale = BoolItem(_("logarithmic"), _("Z-axis scale"), default=False)
computation = ChoiceItem(_("Computation"),
[(-1, _("Bin count")),
(0, _("Maximum value")),
(1, _("Mininum value")),
(2, _("Sum")),
(3, _("Product")),
(4, _("Average")),
],
default=-1,
help=_("Bin count : counts the number of points per bin,\n"
"For max, min, sum, product, average, compute the "
"function of a third parameter (one by default)"))
auto_lut = BoolItem(_("Automatic LUT range"), default=True,
help=_("Automatically adapt color scale "
"when panning, zooming"))
background = ColorItem(_("Background color"), default="transparent",
help=_("Background color when no data is present"))
def update_param(self, obj):
super(Histogram2DParam, self).update_param(obj)
self.logscale = obj.logscale
self.nx_bins, self.ny_bins = obj.nx_bins, obj.ny_bins
def update_histogram(self, histogram):
histogram.logscale = int(self.logscale)
histogram.set_background_color(self.background)
histogram.set_bins(self.nx_bins, self.ny_bins)
self.update_image(histogram)
class Histogram2DParam_MS(Histogram2DParam):
_multiselection = True
ItemParameters.register_multiselection(Histogram2DParam, Histogram2DParam_MS)
# ===================================================
# Shape parameters
# ===================================================
class MarkerParam(DataSet):
[docs] _styles = BeginTabGroup("Styles")
#------------------------------------------------------------------ Line tab
___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png")
line = LineStyleItem(_("Line (not selected)"))
sel_line = LineStyleItem(_("Line (selected)"))
___eline = EndGroup(_("Line"))
#---------------------------------------------------------------- Symbol tab
___sym = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png")
symbol = SymbolItem(_("Symbol (not selected)"))
sel_symbol = SymbolItem(_("Symbol (selected)"))
___esym = EndGroup(_("Symbol"))
#------------------------------------------------------------------ Text tab
___text = BeginGroup(_("Text")).set_prop("display", icon="font.png")
text = TextStyleItem(_("Text (not selected)"))
sel_text = TextStyleItem(_("Text (selected)"))
___etext = EndGroup(_("Text"))
#----------------------------------------------------------------------- End
_endstyles = EndTabGroup("Styles")
markerstyle = ImageChoiceItem(_("Line style"), MARKERSTYLE_CHOICES,
default="NoLine")
spacing = IntItem(_("Spacing"), default=10, min=0)
def update_param(self, obj):
self.symbol.update_param(obj.symbol())
self.text.update_param(obj.label())
self.line.update_param(obj.linePen())
self.markerstyle = MARKERSTYLE_NAME[obj.lineStyle()]
self.spacing = obj.spacing()
def update_marker(self, obj):
if obj.selected:
line = self.sel_line
symb = self.sel_symbol
text = self.sel_text
else:
line = self.line
symb = self.symbol
text = self.text
symb.update_symbol(obj)
label = obj.label()
text.update_text(label)
obj.setLabel(label)
obj.setLinePen(line.build_pen())
obj.setLineStyle(getattr(QwtPlotMarker, self.markerstyle))
obj.setSpacing(self.spacing)
obj.update_label()
def set_markerstyle(self, style):
[docs] """
Set marker line style
style:
* convenient values: '+', '-', '|' or None
* QwtPlotMarker.NoLine, QwtPlotMarker.Vertical, ...
"""
self.markerstyle = MARKERSTYLES.get(style, style)
class ShapeParam(DataSet):
[docs] label = StringItem(_("Title"), default=u"")
_styles = BeginTabGroup("Styles")
#------------------------------------------------------------------ Line tab
___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png")
line = LineStyleItem(_("Line (not selected)"))
sel_line = LineStyleItem(_("Line (selected)"))
___eline = EndGroup(_("Line"))
#---------------------------------------------------------------- Symbol tab
___sym = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png")
symbol = SymbolItem(_("Symbol (not selected)"))
sel_symbol = SymbolItem(_("Symbol (selected)"))
___esym = EndGroup(_("Symbol"))
#------------------------------------------------------------------ Fill tab
___fill = BeginGroup(_("Fill pattern")).set_prop("display",
icon="dense6pattern.png")
fill = BrushStyleItem(_("Fill pattern (not selected)"))
sel_fill = BrushStyleItem(_("Fill pattern (selected)"))
___efill = EndGroup(_("Fill pattern"))
#----------------------------------------------------------------------- End
_endstyles = EndTabGroup("Styles")
readonly = BoolItem(_("Read-only shape"), default=False,
help=_("Read-only shapes can't be removed from "
"the item list panel"))
private = BoolItem(_("Private shape"), default=False,
help=_("Private shapes are not shown in "
"the item list panel")).set_pos(col=1)
def update_param(self, obj):
self.label = unicode(obj.title().text())
self.line.update_param(obj.pen)
self.symbol.update_param(obj.symbol)
self.fill.update_param(obj.brush)
self.sel_line.update_param(obj.sel_pen)
self.sel_symbol.update_param(obj.sel_symbol)
self.sel_fill.update_param(obj.sel_brush)
self.readonly = obj.is_readonly()
self.private = obj.is_private()
def update_shape(self, obj):
obj.setTitle(self.label)
obj.pen = self.line.build_pen()
obj.symbol = self.symbol.build_symbol()
obj.brush = self.fill.build_brush()
obj.sel_pen = self.sel_line.build_pen()
obj.sel_symbol = self.sel_symbol.build_symbol()
obj.sel_brush = self.sel_fill.build_brush()
obj.set_readonly(self.readonly)
obj.set_private(self.private)
class AxesShapeParam(DataSet):
[docs] arrow_angle = FloatItem(_("Arrow angle (°)"), min=0, max=90, nonzero=True)
arrow_size = FloatItem(_("Arrow size (%)"), min=0, max=100, nonzero=True)
_styles = BeginTabGroup("Styles")
#------------------------------------------------------------------ Line tab
___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png")
xarrow_pen = LineStyleItem(_("Line (X-Axis)"))
yarrow_pen = LineStyleItem(_("Line (Y-Axis)"))
___eline = EndGroup(_("Line"))
#------------------------------------------------------------------ Fill tab
___fill = BeginGroup(_("Fill pattern")).set_prop("display",
icon="dense6pattern.png")
xarrow_brush = BrushStyleItem(_("Fill pattern (X-Axis)"))
yarrow_brush = BrushStyleItem(_("Fill pattern (Y-Axis)"))
___efill = EndGroup(_("Fill pattern"))
#----------------------------------------------------------------------- End
_endstyles = EndTabGroup("Styles")
def update_param(self, obj):
self.arrow_angle = obj.arrow_angle
self.arrow_size = obj.arrow_size
self.xarrow_pen.update_param(obj.x_pen)
self.yarrow_pen.update_param(obj.y_pen)
self.xarrow_brush.update_param(obj.x_brush)
self.yarrow_brush.update_param(obj.y_brush)
def update_axes(self, obj):
obj.arrow_angle = self.arrow_angle
obj.arrow_size = self.arrow_size
obj.x_pen = self.xarrow_pen.build_pen()
obj.x_brush = self.xarrow_brush.build_brush()
obj.y_pen = self.yarrow_pen.build_pen()
obj.y_brush = self.yarrow_brush.build_brush()
class AnnotationParam(DataSet):
[docs] show_label = BoolItem(_("Show annotation"), default=True)
show_computations = BoolItem(_("Show informations on area "
"covered by this shape"), default=True)
title = StringItem(_("Title"), default=u"")
subtitle = StringItem(_("Subtitle"), default=u"")
format = StringItem(_("String formatting"), default="%.1f")
uncertainty = FloatItem(_("Uncertainty"), default=0., min=0., max=1.,
help=_("Measurement relative uncertainty")
).set_pos(col=1)
transform_matrix = FloatArrayItem(_("Transform matrix"),
default=np.eye(3, dtype=float))
readonly = BoolItem(_("Read-only shape"), default=False,
help=_("Read-only shapes can't be removed from "
"the item list panel"))
private = BoolItem(_("Private shape"), default=False,
help=_("Private shapes are not shown in "
"the item list panel")).set_pos(col=1)
def update_param(self, obj):
self.show_label = obj.is_label_visible()
self.show_computations = obj.area_computations_visible
self.title = unicode(obj.title().text())
self.readonly = obj.is_readonly()
self.private = obj.is_private()
def update_annotation(self, obj):
obj.setTitle(self.title)
obj.set_label_visible(self.show_label)
obj.area_computations_visible = self.show_computations
obj.update_label()
obj.set_readonly(self.readonly)
obj.set_private(self.private)
# ===================================================
# Range selection parameters
# ===================================================
class RangeShapeParam(DataSet):
[docs] _styles = BeginTabGroup("Styles")
#------------------------------------------------------------------ Line tab
___line = BeginGroup(_("Line")).set_prop("display", icon="dashdot.png")
line = LineStyleItem(_("Line (not selected)"))
sel_line = LineStyleItem(_("Line (selected)"))
___eline = EndGroup(_("Line"))
#---------------------------------------------------------------- Symbol tab
___symbol = BeginGroup(_("Symbol")).set_prop("display", icon="diamond.png")
symbol = SymbolItem(_("Symbol (not selected)"))
sel_symbol = SymbolItem(_("Symbol (selected)"))
___esymbol = EndGroup(_("Symbol"))
#------------------------------------------------------------------ Fill tab
___fill = BeginGroup(_("Fill")).set_prop("display",
icon="dense6pattern.png")
fill = ColorItem(_("Fill color"))
shade = FloatItem(_("Shade"), default = .05, min=0, max=1)
___efill = EndGroup(_("Fill"))
#----------------------------------------------------------------------- End
_endstyles = EndTabGroup("Styles")
def update_param(self, range):
self.line.update_param(range.pen)
self.sel_line.update_param(range.sel_pen)
self.fill = range.brush.color().name()
self.shade = range.brush.color().alphaF()
self.symbol.update_param(range.symbol)
self.sel_symbol.update_param(range.sel_symbol)
def update_range(self, range):
range.pen = self.line.build_pen()
range.sel_pen = self.sel_line.build_pen()
col = QColor(self.fill)
col.setAlphaF(self.shade)
range.brush = QBrush(col)
range.symbol = self.symbol.build_symbol()
range.sel_symbol = self.sel_symbol.build_symbol()