From efa662415e84008a40f56aa0c075b1ae2133dc4d Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Mon, 2 Aug 2021 19:00:38 +0800 Subject: [PATCH 1/4] use QColor methods and functions --- doc/source/functions.rst | 19 ++++++++++++------ examples/GLLinePlotItem.py | 3 +-- pyqtgraph/colormap.py | 18 ++++++++--------- pyqtgraph/exporters/Matplotlib.py | 8 ++++---- pyqtgraph/functions.py | 20 ++++++------------- pyqtgraph/graphicsItems/AxisItem.py | 4 ++-- pyqtgraph/graphicsItems/GradientEditorItem.py | 17 ++++++++-------- pyqtgraph/graphicsItems/LabelItem.py | 2 +- pyqtgraph/graphicsItems/PlotCurveItem.py | 3 +-- pyqtgraph/graphicsItems/PlotItem/PlotItem.py | 18 ++++++++--------- pyqtgraph/opengl/GLViewWidget.py | 4 ++-- pyqtgraph/opengl/items/GLBoxItem.py | 4 ++-- pyqtgraph/opengl/items/GLGridItem.py | 4 ++-- pyqtgraph/opengl/items/GLLinePlotItem.py | 10 ++++++---- pyqtgraph/opengl/items/GLMeshItem.py | 5 ++--- pyqtgraph/opengl/items/GLScatterPlotItem.py | 8 ++++---- .../parametertree/parameterTypes/color.py | 2 +- pyqtgraph/widgets/ColorButton.py | 6 +++--- pyqtgraph/widgets/ColorMapWidget.py | 8 ++++---- 19 files changed, 79 insertions(+), 84 deletions(-) diff --git a/doc/source/functions.rst b/doc/source/functions.rst index c4183fc3..7fe2153d 100644 --- a/doc/source/functions.rst +++ b/doc/source/functions.rst @@ -34,12 +34,6 @@ Qt uses the classes QColor, QPen, and QBrush to determine how to draw lines and .. autofunction:: pyqtgraph.colorCIELab -.. autofunction:: pyqtgraph.colorTuple - -.. autofunction:: pyqtgraph.colorStr - -.. autofunction:: pyqtgraph.glColor - .. autofunction:: pyqtgraph.colorDistance @@ -108,3 +102,16 @@ Miscellaneous Functions .. autofunction:: pyqtgraph.systemInfo .. autofunction:: pyqtgraph.exit + + +Legacy Color Helper Functions +------------------------------- + +The following helper functions should no longer be used. The functionality that they implement is trivial and it is suggested that the user use the equivalent QColor methods directly. + + +.. autofunction:: pyqtgraph.colorTuple + +.. autofunction:: pyqtgraph.colorStr + +.. autofunction:: pyqtgraph.glColor diff --git a/examples/GLLinePlotItem.py b/examples/GLLinePlotItem.py index 9e60921e..d4156f67 100644 --- a/examples/GLLinePlotItem.py +++ b/examples/GLLinePlotItem.py @@ -6,7 +6,6 @@ Demonstrate use of GLLinePlotItem to draw cross-sections of a surface. ## Add path to library (just for examples; you do not need this) import initExample -from pyqtgraph.Qt import QtCore, QtGui import pyqtgraph.opengl as gl import pyqtgraph as pg import numpy as np @@ -37,7 +36,7 @@ for i in range(n): d = np.hypot(x, yi) z = 10 * np.cos(d) / (d+1) pts = np.column_stack([x, np.full_like(x, yi), z]) - plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3)), width=(i+1)/10., antialias=True) + plt = gl.GLLinePlotItem(pos=pts, color=pg.mkColor((i,n*1.3)), width=(i+1)/10., antialias=True) w.addItem(plt) if __name__ == '__main__': diff --git a/pyqtgraph/colormap.py b/pyqtgraph/colormap.py index b75b188d..7bd4981b 100644 --- a/pyqtgraph/colormap.py +++ b/pyqtgraph/colormap.py @@ -249,8 +249,7 @@ def makeHslCycle( hue=0.0, saturation=1.0, lightness=0.5, steps=36 ): lgt_vals = np.linspace(lgtA, lgtB, num=steps+1) color_list = [] for hue, sat, lgt in zip( hue_vals, sat_vals, lgt_vals): - qcol = QtGui.QColor() - qcol.setHslF( hue%1.0, sat, lgt ) + qcol = QtGui.QColor.fromHslF( hue%1.0, sat, lgt ) color_list.append( qcol ) name = f'Hue {hueA:0.2f}-{hueB:0.2f}' return ColorMap( None, color_list, name=name ) @@ -311,8 +310,7 @@ def makeMonochrome(color='neutral'): l_vals = np.linspace(l_min, l_max, num=16) color_list = [] for l_val in l_vals: - qcol = QtGui.QColor() - qcol.setHslF( h_val, s_val, l_val ) + qcol = QtGui.QColor.fromHslF( h_val, s_val, l_val ) color_list.append( qcol ) return ColorMap( None, color_list, name=name, linearize=True ) @@ -581,7 +579,7 @@ class ColorMap(object): mode = self.enumMap[mode.lower()] if mode == self.QCOLOR: - pos, color = self.getStops(self.BYTE) + pos, color = self.getStops(self.FLOAT) else: pos, color = self.getStops(mode) @@ -606,9 +604,9 @@ class ColorMap(object): # Convert to QColor if requested if mode == self.QCOLOR: if np.isscalar(data): - return QtGui.QColor(*interp) + return QtGui.QColor.fromRgbF(*interp) else: - return [QtGui.QColor(*x.tolist()) for x in interp] + return [QtGui.QColor.fromRgbF(*x.tolist()) for x in interp] else: return interp @@ -762,8 +760,10 @@ class ColorMap(object): color = color.astype(float) / 255. elif mode == self.QCOLOR: if color.dtype.kind == 'f': - color = (color*255).astype(np.ubyte) - color = [QtGui.QColor(*x.tolist()) for x in color] + factory = QtGui.QColor.fromRgbF + else: + factory = QtGui.QColor.fromRgb + color = [factory(*x.tolist()) for x in color] self.stopsCache[mode] = (self.pos, color) return self.stopsCache[mode] diff --git a/pyqtgraph/exporters/Matplotlib.py b/pyqtgraph/exporters/Matplotlib.py index f378ad4e..8e21f348 100644 --- a/pyqtgraph/exporters/Matplotlib.py +++ b/pyqtgraph/exporters/Matplotlib.py @@ -95,19 +95,19 @@ class MatplotlibExporter(Exporter): linestyle = '' else: linestyle = '-' - color = tuple([c/255. for c in fn.colorTuple(pen.color())]) + color = pen.color().getRgbF() symbol = opts['symbol'] if symbol == 't': symbol = '^' symbolPen = fn.mkPen(opts['symbolPen']) symbolBrush = fn.mkBrush(opts['symbolBrush']) - markeredgecolor = tuple([c/255. for c in fn.colorTuple(symbolPen.color())]) - markerfacecolor = tuple([c/255. for c in fn.colorTuple(symbolBrush.color())]) + markeredgecolor = symbolPen.color().getRgbF() + markerfacecolor = symbolBrush.color().getRgbF() markersize = opts['symbolSize'] if opts['fillLevel'] is not None and opts['fillBrush'] is not None: fillBrush = fn.mkBrush(opts['fillBrush']) - fillcolor = tuple([c/255. for c in fn.colorTuple(fillBrush.color())]) + fillcolor = fillBrush.color().getRgbF() ax.fill_between(x=x, y1=y, y2=opts['fillLevel'], facecolor=fillcolor) pl = ax.plot(x, y, marker=symbol, color=color, linewidth=pen.width(), diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index ffaf510e..464a5b10 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -224,7 +224,7 @@ class Color(QtGui.QColor): def glColor(self): """Return (r,g,b,a) normalized for use in opengl""" - return (self.red()/255., self.green()/255., self.blue()/255., self.alpha()/255.) + return self.getRgbF() def __getitem__(self, ind): return (self.red, self.green, self.blue, self.alpha)[ind]() @@ -390,9 +390,7 @@ def mkPen(*args, **kargs): def hsvColor(hue, sat=1.0, val=1.0, alpha=1.0): """Generate a QColor from HSVa values. (all arguments are float 0.0-1.0)""" - c = QtGui.QColor() - c.setHsvF(hue, sat, val, alpha) - return c + return QtGui.QColor.fromHsvF(hue, sat, val, alpha) # Matrices and math taken from "CIELab Color Space" by Gernot Hoffmann # http://docs-hoffmann.de/cielab03022003.pdf @@ -475,10 +473,7 @@ def CIELabColor(L, a, b, alpha=1.0): else: arr_sRGB[idx] = 12.92 * val # (s) arr_sRGB = clip_array( arr_sRGB, 0.0, 1.0 ) # avoid QColor errors - qcol = QtGui.QColor() - qcol.setRgbF( *arr_sRGB ) - if alpha < 1.0: qcol.setAlpha(alpha) - return qcol + return QtGui.QColor.fromRgbF( *arr_sRGB, alpha ) def colorCIELab(qcol): """ @@ -555,7 +550,7 @@ def colorDistance(colors, metric='CIE76'): def colorTuple(c): """Return a tuple (R,G,B,A) from a QColor""" - return (c.red(), c.green(), c.blue(), c.alpha()) + return c.getRgb() def colorStr(c): """Generate a hex string code from a QColor""" @@ -581,10 +576,7 @@ def intColor(index, hues=9, values=1, maxValue=255, minValue=150, maxHue=360, mi v = maxValue h = minHue + (indh * (maxHue-minHue)) // hues - c = QtGui.QColor() - c.setHsv(h, sat, v) - c.setAlpha(alpha) - return c + return QtGui.QColor.fromHsv(h, sat, v, alpha) def glColor(*args, **kargs): @@ -593,7 +585,7 @@ def glColor(*args, **kargs): Accepts same arguments as :func:`mkColor `. """ c = mkColor(*args, **kargs) - return (c.red()/255., c.green()/255., c.blue()/255., c.alpha()/255.) + return c.getRgbF() diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py index 2f338953..15176fe8 100644 --- a/pyqtgraph/graphicsItems/AxisItem.py +++ b/pyqtgraph/graphicsItems/AxisItem.py @@ -433,7 +433,7 @@ class AxisItem(GraphicsWidget): self._pen = fn.mkPen(*args, **kwargs) else: self._pen = fn.mkPen(getConfigOption('foreground')) - self.labelStyle['color'] = '#' + fn.colorStr(self._pen.color())[:6] + self.labelStyle['color'] = self._pen.color().name() # #RRGGBB self._updateLabel() def textPen(self): @@ -451,7 +451,7 @@ class AxisItem(GraphicsWidget): self._textPen = fn.mkPen(*args, **kwargs) else: self._textPen = fn.mkPen(getConfigOption('foreground')) - self.labelStyle['color'] = '#' + fn.colorStr(self._textPen.color())[:6] + self.labelStyle['color'] = self._textPen.color().name() # #RRGGBB self._updateLabel() def setScale(self, scale=None): diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py index 1bddd35f..2832f3f9 100644 --- a/pyqtgraph/graphicsItems/GradientEditorItem.py +++ b/pyqtgraph/graphicsItems/GradientEditorItem.py @@ -581,7 +581,7 @@ class GradientEditorItem(TickSliderItem): for t,x in self.listTicks(): pos.append(x) c = t.color - color.append([c.red(), c.green(), c.blue(), c.alpha()]) + color.append(c.getRgb()) return ColorMap(np.array(pos), np.array(color, dtype=np.ubyte)) def updateGradient(self): @@ -671,13 +671,13 @@ class GradientEditorItem(TickSliderItem): if toQColor: return QtGui.QColor(c) # always copy colors before handing them out else: - return (c.red(), c.green(), c.blue(), c.alpha()) + return c.getRgb() if x >= ticks[-1][1]: c = ticks[-1][0].color if toQColor: return QtGui.QColor(c) # always copy colors before handing them out else: - return (c.red(), c.green(), c.blue(), c.alpha()) + return c.getRgb() x2 = ticks[0][1] for i in range(1,len(ticks)): @@ -708,12 +708,11 @@ class GradientEditorItem(TickSliderItem): h = h1 * (1.-f) + h2 * f s = s1 * (1.-f) + s2 * f v = v1 * (1.-f) + v2 * f - c = QtGui.QColor() - c.setHsv(*map(int, [h,s,v])) + c = QtGui.QColor.fromHsv(int(h), int(s), int(v)) if toQColor: return c else: - return (c.red(), c.green(), c.blue(), c.alpha()) + return c.getRgb() def getLookupTable(self, nPts, alpha=None): """ @@ -757,8 +756,8 @@ class GradientEditorItem(TickSliderItem): return False if ticks[0][1] != 0.0 or ticks[1][1] != 1.0: return False - c1 = fn.colorTuple(ticks[0][0].color) - c2 = fn.colorTuple(ticks[1][0].color) + c1 = ticks[0][0].color.getRgb() + c2 = ticks[1][0].color.getRgb() if c1 != (0,0,0,255) or c2 != (255,255,255,255): return False return True @@ -794,7 +793,7 @@ class GradientEditorItem(TickSliderItem): ticks = [] for t in self.ticks: c = t.color - ticks.append((self.ticks[t], (c.red(), c.green(), c.blue(), c.alpha()))) + ticks.append((self.ticks[t], c.getRgb())) state = {'mode': self.colorMode, 'ticks': ticks, 'ticksVisible': next(iter(self.ticks)).isVisible()} diff --git a/pyqtgraph/graphicsItems/LabelItem.py b/pyqtgraph/graphicsItems/LabelItem.py index 968c8713..85a6f3c5 100644 --- a/pyqtgraph/graphicsItems/LabelItem.py +++ b/pyqtgraph/graphicsItems/LabelItem.py @@ -56,7 +56,7 @@ class LabelItem(GraphicsWidget, GraphicsWidgetAnchor): if color is None: color = getConfigOption('foreground') color = fn.mkColor(color) - optlist.append('color: #' + fn.colorStr(color)[:6]) + optlist.append('color: ' + color.name()) if 'size' in opts: optlist.append('font-size: ' + opts['size']) if 'bold' in opts and opts['bold'] in [True, False]: diff --git a/pyqtgraph/graphicsItems/PlotCurveItem.py b/pyqtgraph/graphicsItems/PlotCurveItem.py index 9aca7d76..3a28be77 100644 --- a/pyqtgraph/graphicsItems/PlotCurveItem.py +++ b/pyqtgraph/graphicsItems/PlotCurveItem.py @@ -620,8 +620,7 @@ class PlotCurveItem(GraphicsObject): try: gl.glVertexPointerf(pos) pen = fn.mkPen(self.opts['pen']) - color = pen.color() - gl.glColor4f(color.red()/255., color.green()/255., color.blue()/255., color.alpha()/255.) + gl.glColor4f(*pen.color().getRgbF()) width = pen.width() if pen.isCosmetic() and width < 1: width = 1 diff --git a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py index d8b9893f..e559d13a 100644 --- a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py +++ b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py @@ -763,9 +763,8 @@ class PlotItem(GraphicsWidget): for item in self.curves: if isinstance(item, PlotCurveItem): - color = fn.colorStr(item.pen.color()) - opacity = item.pen.color().alpha() / 255. - color = color[:6] + color = item.pen.color() + hrrggbb, opacity = color.name(), color.alphaF() x, y = item.getData() mask = (x > xRange[0]) * (x < xRange[1]) mask[:-1] += mask[1:] @@ -780,9 +779,9 @@ class PlotItem(GraphicsWidget): # fh.write('\n' % ( # color, )) - fh.write('\n' % ( - x, y, color, opacity)) + x, y, hrrggbb, opacity)) fh.write("\n") diff --git a/pyqtgraph/opengl/GLViewWidget.py b/pyqtgraph/opengl/GLViewWidget.py index f311c776..a44d9edc 100644 --- a/pyqtgraph/opengl/GLViewWidget.py +++ b/pyqtgraph/opengl/GLViewWidget.py @@ -138,9 +138,9 @@ class GLViewWidget(QtWidgets.QOpenGLWidget): def setBackgroundColor(self, *args, **kwds): """ Set the background color of the widget. Accepts the same arguments as - pg.mkColor() and pg.glColor(). + :func:`~pyqtgraph.mkColor`. """ - self.opts['bgcolor'] = fn.glColor(*args, **kwds) + self.opts['bgcolor'] = fn.mkColor(*args, **kwds).getRgbF() self.update() def getViewport(self): diff --git a/pyqtgraph/opengl/items/GLBoxItem.py b/pyqtgraph/opengl/items/GLBoxItem.py index f0a6ae6c..7c7f0156 100644 --- a/pyqtgraph/opengl/items/GLBoxItem.py +++ b/pyqtgraph/opengl/items/GLBoxItem.py @@ -38,7 +38,7 @@ class GLBoxItem(GLGraphicsItem): def setColor(self, *args): """Set the color of the box. Arguments are the same as those accepted by functions.mkColor()""" - self.__color = fn.Color(*args) + self.__color = fn.mkColor(*args) def color(self): return self.__color @@ -54,7 +54,7 @@ class GLBoxItem(GLGraphicsItem): glBegin( GL_LINES ) - glColor4f(*self.color().glColor()) + glColor4f(*self.color().getRgbF()) x,y,z = self.size() glVertex3f(0, 0, 0) glVertex3f(0, 0, z) diff --git a/pyqtgraph/opengl/items/GLGridItem.py b/pyqtgraph/opengl/items/GLGridItem.py index 9dcff070..b07acece 100644 --- a/pyqtgraph/opengl/items/GLGridItem.py +++ b/pyqtgraph/opengl/items/GLGridItem.py @@ -56,7 +56,7 @@ class GLGridItem(GLGraphicsItem): def setColor(self, color): """Set the color of the grid. Arguments are the same as those accepted by functions.mkColor()""" - self.__color = fn.Color(color) + self.__color = fn.mkColor(color) self.update() def color(self): @@ -77,7 +77,7 @@ class GLGridItem(GLGraphicsItem): xs,ys,zs = self.spacing() xvals = np.arange(-x/2., x/2. + xs*0.001, xs) yvals = np.arange(-y/2., y/2. + ys*0.001, ys) - glColor4f(*self.color().glColor()) + glColor4f(*self.color().getRgbF()) for x in xvals: glVertex3f(x, yvals[0], 0) glVertex3f(x, yvals[-1], 0) diff --git a/pyqtgraph/opengl/items/GLLinePlotItem.py b/pyqtgraph/opengl/items/GLLinePlotItem.py index ad593ef1..c608f244 100644 --- a/pyqtgraph/opengl/items/GLLinePlotItem.py +++ b/pyqtgraph/opengl/items/GLLinePlotItem.py @@ -66,10 +66,12 @@ class GLLinePlotItem(GLGraphicsItem): glEnableClientState(GL_COLOR_ARRAY) glColorPointerf(self.color) else: - if isinstance(self.color, (str, QtGui.QColor)): - glColor4f(*fn.glColor(self.color)) - else: - glColor4f(*self.color) + color = self.color + if isinstance(color, str): + color = fn.mkColor(color) + if isinstance(color, QtGui.QColor): + color = color.getRgbF() + glColor4f(*color) glLineWidth(self.width) if self.antialias: diff --git a/pyqtgraph/opengl/items/GLMeshItem.py b/pyqtgraph/opengl/items/GLMeshItem.py index e5379ae2..1bc182ea 100644 --- a/pyqtgraph/opengl/items/GLMeshItem.py +++ b/pyqtgraph/opengl/items/GLMeshItem.py @@ -3,7 +3,6 @@ from .. GLGraphicsItem import GLGraphicsItem from .. MeshData import MeshData from ...Qt import QtGui from .. import shaders -from ... import functions as fn import numpy as np @@ -181,7 +180,7 @@ class GLMeshItem(GLGraphicsItem): if self.colors is None: color = self.opts['color'] if isinstance(color, QtGui.QColor): - glColor4f(*fn.glColor(color)) + glColor4f(*color.getRgbF()) else: glColor4f(*color) else: @@ -213,7 +212,7 @@ class GLMeshItem(GLGraphicsItem): if self.edgeColors is None: color = self.opts['edgeColor'] if isinstance(color, QtGui.QColor): - glColor4f(*fn.glColor(color)) + glColor4f(*color.getRgbF()) else: glColor4f(*color) else: diff --git a/pyqtgraph/opengl/items/GLScatterPlotItem.py b/pyqtgraph/opengl/items/GLScatterPlotItem.py index 3aa42aa7..81fc7400 100644 --- a/pyqtgraph/opengl/items/GLScatterPlotItem.py +++ b/pyqtgraph/opengl/items/GLScatterPlotItem.py @@ -126,10 +126,10 @@ class GLScatterPlotItem(GLGraphicsItem): glEnableClientState(GL_COLOR_ARRAY) glColorPointerf(self.color) else: - if isinstance(self.color, QtGui.QColor): - glColor4f(*fn.glColor(self.color)) - else: - glColor4f(*self.color) + color = self.color + if isinstance(color, QtGui.QColor): + color = color.getRgbF() + glColor4f(*color) if not self.pxMode or isinstance(self.size, np.ndarray): glEnableClientState(GL_NORMAL_ARRAY) diff --git a/pyqtgraph/parametertree/parameterTypes/color.py b/pyqtgraph/parametertree/parameterTypes/color.py index 86655177..cebbf829 100644 --- a/pyqtgraph/parametertree/parameterTypes/color.py +++ b/pyqtgraph/parametertree/parameterTypes/color.py @@ -27,5 +27,5 @@ class ColorParameter(SimpleParameter): def saveState(self, filter=None): state = super().saveState(filter) - state['value'] = fn.colorTuple(self.value()) + state['value'] = self.value().getRgb() return state diff --git a/pyqtgraph/widgets/ColorButton.py b/pyqtgraph/widgets/ColorButton.py index ecbc60b0..f1982adf 100644 --- a/pyqtgraph/widgets/ColorButton.py +++ b/pyqtgraph/widgets/ColorButton.py @@ -72,7 +72,7 @@ class ColorButton(QtGui.QPushButton): self.setColor(self._color, finished=True) def saveState(self): - return functions.colorTuple(self._color) + return self._color.getRgb() def restoreState(self, state): self.setColor(state) @@ -82,9 +82,9 @@ class ColorButton(QtGui.QPushButton): if mode == 'qcolor': return color elif mode == 'byte': - return (color.red(), color.green(), color.blue(), color.alpha()) + return color.getRgb() elif mode == 'float': - return (color.red()/255., color.green()/255., color.blue()/255., color.alpha()/255.) + return color.getRgbF() def widgetGroupInterface(self): return (self.sigColorChanged, ColorButton.saveState, ColorButton.restoreState) diff --git a/pyqtgraph/widgets/ColorMapWidget.py b/pyqtgraph/widgets/ColorMapWidget.py index 5690e53c..affe9b6b 100644 --- a/pyqtgraph/widgets/ColorMapWidget.py +++ b/pyqtgraph/widgets/ColorMapWidget.py @@ -217,7 +217,7 @@ class RangeColorMapItem(ptree.types.SimpleParameter): mask = np.invert(np.isfinite(data)) nanColor = self['NaN'] - nanColor = (nanColor.red()/255., nanColor.green()/255., nanColor.blue()/255., nanColor.alpha()/255.) + nanColor = nanColor.getRgbF() colors[mask] = nanColor return colors @@ -254,12 +254,12 @@ class EnumColorMapItem(ptree.types.GroupParameter): def map(self, data): data = data[self.fieldName] colors = np.empty((len(data), 4)) - default = np.array(fn.colorTuple(self['Default'])) / 255. + default = np.array(self['Default'].getRgbF()) colors[:] = default for v in self.param('Values'): mask = data == v.maskValue - c = np.array(fn.colorTuple(v.value())) / 255. + c = np.array(v.value().getRgbF()) colors[mask] = c #scaled = np.clip((data-self['Min']) / (self['Max']-self['Min']), 0, 1) #cmap = self.value() @@ -267,7 +267,7 @@ class EnumColorMapItem(ptree.types.GroupParameter): #mask = np.isnan(data) | np.isinf(data) #nanColor = self['NaN'] - #nanColor = (nanColor.red()/255., nanColor.green()/255., nanColor.blue()/255., nanColor.alpha()/255.) + #nanColor = nanColor.getRgbF() #colors[mask] = nanColor return colors From 482b92d700bc544c3ce65fc1a7aaba2c4792c24c Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Tue, 3 Aug 2021 20:29:11 +0800 Subject: [PATCH 2/4] GLGradientLegendItem: remove opengl code change fontColor to take a mkColor() argument use hyperlink when referring to other functions --- .../opengl/items/GLGradientLegendItem.py | 70 ++++++------------- 1 file changed, 23 insertions(+), 47 deletions(-) diff --git a/pyqtgraph/opengl/items/GLGradientLegendItem.py b/pyqtgraph/opengl/items/GLGradientLegendItem.py index 1409a160..eb33a886 100644 --- a/pyqtgraph/opengl/items/GLGradientLegendItem.py +++ b/pyqtgraph/opengl/items/GLGradientLegendItem.py @@ -1,6 +1,6 @@ from ... Qt import QtCore, QtGui from ... import functions as fn -from OpenGL.GL import * +from ... colormap import ColorMap from ..GLGraphicsItem import GLGraphicsItem __all__ = ['GLGradientLegendItem'] @@ -18,7 +18,8 @@ class GLGradientLegendItem(GLGraphicsItem): gradient: a pg.ColorMap used to color the colorbar labels: a dict of "text":value to display next to the colorbar. The value corresponds to a position in the gradient from 0 to 1. - fontColor: sets the color of the texts + fontColor: sets the color of the texts. Accepts any single argument accepted by + :func:`~pyqtgraph.mkColor` #Todo: size as percentage legend title @@ -28,10 +29,12 @@ class GLGradientLegendItem(GLGraphicsItem): self.setGLOptions(glopts) self.pos = (10, 10) self.size = (10, 100) - self.fontColor = (1.0, 1.0, 1.0, 1.0) - self.stops = None - self.colors = None - self.gradient = None + self.fontColor = QtGui.QColor(QtCore.Qt.GlobalColor.white) + # setup a default trivial gradient + stops = (0.0, 1.0) + self.gradient = ColorMap(pos=stops, color=(0.0, 1.0)) + self._gradient = None + self.labels = {str(x) : x for x in stops} self.setData(**kwds) def setData(self, **kwds): @@ -45,54 +48,31 @@ class GLGradientLegendItem(GLGraphicsItem): self.antialias = False - for arg in args: - if arg in kwds: - setattr(self, arg, kwds[arg]) + for key in kwds: + value = kwds[key] + if key == 'fontColor': + value = fn.mkColor(value) + elif key == 'gradient': + self._gradient = None + setattr(self, key, value) ##todo: add title ##todo: take more gradient types - if self.gradient is not None and hasattr(self.gradient, "getStops"): - self.stops, self.colors = self.gradient.getStops("float") - self.qgradient = self.gradient.getGradient() self.update() def paint(self): - if self.pos is None or self.stops is None: - return self.setupGLState() - glMatrixMode(GL_PROJECTION) - glPushMatrix() - glLoadIdentity() - glOrtho(0.0, self.view().width(), self.view().height(), 0.0, -1.0, 10.0) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - glDisable(GL_CULL_FACE) - glClear(GL_DEPTH_BUFFER_BIT) + if self._gradient is None: + self._gradient = self.gradient.getGradient() - # draw the colorbar - glTranslate(self.pos[0], self.pos[1], 0) - glScale(self.size[0], self.size[1], 0) - glBegin(GL_QUAD_STRIP) - for p, c in zip(self.stops, self.colors): - glColor4f(*c) - glVertex2d(0, 1 - p) - glColor4f(*c) - glVertex2d(1, 1 - p) - glEnd() - - # draw labels - # scaling and translate doesnt work on rendertext - fontColor = QtGui.QColor(*[x * 255 for x in self.fontColor]) - - # could also draw the gradient using QPainter - barRect = QtCore.QRectF(self.view().width() - 60, self.pos[1], self.size[0], self.size[1]) - self.qgradient.setStart(barRect.bottomLeft()) - self.qgradient.setFinalStop(barRect.topLeft()) + barRect = QtCore.QRectF(self.pos[0], self.pos[1], self.size[0], self.size[1]) + self._gradient.setStart(barRect.bottomLeft()) + self._gradient.setFinalStop(barRect.topLeft()) painter = QtGui.QPainter(self.view()) - painter.fillRect(barRect, self.qgradient) - painter.setPen(fn.mkPen(fontColor)) + painter.fillRect(barRect, self._gradient) + painter.setPen(self.fontColor) for labelText, labelPosition in self.labels.items(): ## todo: draw ticks, position text properly x = 1.1 * self.size[0] + self.pos[0] @@ -101,7 +81,3 @@ class GLGradientLegendItem(GLGraphicsItem): painter.drawText(x, y, labelText) painter.end() - glMatrixMode(GL_PROJECTION) - glPopMatrix() - glMatrixMode(GL_MODELVIEW) - From 371facb17fa4eff58152d6854459ba23a79d62c9 Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Wed, 4 Aug 2021 08:28:21 +0800 Subject: [PATCH 3/4] SVGExporter.py : fix background color 1) blue and green were swapped 2) %f used for integer rgb components 3) %d used for float opacity component --- pyqtgraph/exporters/SVGExporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyqtgraph/exporters/SVGExporter.py b/pyqtgraph/exporters/SVGExporter.py index a4b84b65..aefd743f 100644 --- a/pyqtgraph/exporters/SVGExporter.py +++ b/pyqtgraph/exporters/SVGExporter.py @@ -119,7 +119,7 @@ def generateSvg(item, options={}): defsXml += "\n" svgAttributes = ' viewBox ="0 0 %f %f"' % (options["width"], options["height"]) c = options['background'] - backgroundtag = '\n' % (c.red(), c.blue(), c.green(), c.alpha()/255.0) + backgroundtag = '\n' % (c.red(), c.green(), c.blue(), c.alphaF()) return (xmlHeader % svgAttributes) + backgroundtag + defsXml + node.toprettyxml(indent=' ') + "\n\n" From 178e693a4d5e24856a5b4c661adf905e6b9bed0c Mon Sep 17 00:00:00 2001 From: KIU Shueng Chuan Date: Wed, 4 Aug 2021 08:55:29 +0800 Subject: [PATCH 4/4] add SVG named color support --- pyqtgraph/functions.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index 464a5b10..53c1341e 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -258,6 +258,16 @@ def mkColor(*args): return Colors[c] except KeyError: raise ValueError('No color named "%s"' % c) + have_alpha = len(c) in [5, 9] and c[0] == '#' # "#RGBA" and "#RRGGBBAA" + if not have_alpha: + # try parsing SVG named colors, including "#RGB" and "#RRGGBB". + # note that QColor.setNamedColor() treats a 9-char hex string as "#AARRGGBB". + qcol = QtGui.QColor() + qcol.setNamedColor(c) + if qcol.isValid(): + return qcol + # on failure, fallback to pyqtgraph parsing + # this includes the deprecated case of non-#-prefixed hex strings if c[0] == '#': c = c[1:] else: