From 0cbcf69bb2e4807c58daf42e4b6d7fe1bbea8fa8 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 4 May 2016 17:52:34 -0700 Subject: [PATCH 1/2] Minor cleanups for FormLayout. --- .../backends/qt_editor/formlayout.py | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/lib/matplotlib/backends/qt_editor/formlayout.py b/lib/matplotlib/backends/qt_editor/formlayout.py index 9acf9a207f32..34395a5f1e33 100644 --- a/lib/matplotlib/backends/qt_editor/formlayout.py +++ b/lib/matplotlib/backends/qt_editor/formlayout.py @@ -32,38 +32,31 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from __future__ import (absolute_import, division, print_function, - unicode_literals) - -import six -from six.moves import xrange # History: # 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid) # 1.0.7: added support for "Apply" button # 1.0.6: code cleaning +from __future__ import (absolute_import, division, print_function, + unicode_literals) + __version__ = '1.0.10' __license__ = __doc__ DEBUG = False -import sys -STDERR = sys.stderr - -from matplotlib.colors import is_color_like -from matplotlib.colors import rgb2hex -from matplotlib.colors import colorConverter -from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore +import six +import copy import datetime +import warnings -BLACKLIST = set(["title", "label"]) +from matplotlib.colors import colorConverter, is_color_like, rgb2hex +from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore -def col2hex(color): - """Convert matplotlib color to hex before passing to Qt""" - return rgb2hex(colorConverter.to_rgb(color)) +BLACKLIST = set(["title", "label"]) class ColorButton(QtWidgets.QPushButton): @@ -80,7 +73,8 @@ def __init__(self, parent=None): self._color = QtGui.QColor() def choose_color(self): - color = QtWidgets.QColorDialog.getColor(self._color, self.parentWidget(), '') + color = QtWidgets.QColorDialog.getColor( + self._color, self.parentWidget(), '') if color.isValid(): self.set_color(color) @@ -98,10 +92,12 @@ def set_color(self, color): color = QtCore.Property(QtGui.QColor, get_color, set_color) + def col2hex(color): """Convert matplotlib color to hex before passing to Qt""" return rgb2hex(colorConverter.to_rgb(color)) + def to_qcolor(color): """Create a QColor from a matplotlib color""" qcolor = QtGui.QColor() @@ -109,7 +105,7 @@ def to_qcolor(color): try: color = col2hex(color) except ValueError: - #print('WARNING: ignoring invalid color %r' % color) + warnings.warn('Ignoring invalid color %r' % color) return qcolor # return invalid QColor qcolor.setNamedColor(color) # set using hex color return qcolor # return valid QColor @@ -143,7 +139,7 @@ def text(self): def font_is_installed(font): """Check if font is installed""" return [fam for fam in QtGui.QFontDatabase().families() - if six.text_type(fam) == font] + if six.text_type(fam) == font] def tuple_to_qfont(tup): @@ -151,11 +147,11 @@ def tuple_to_qfont(tup): Create a QFont from tuple: (family [string], size [int], italic [bool], bold [bool]) """ - if not isinstance(tup, tuple) or len(tup) != 4 \ - or not font_is_installed(tup[0]) \ - or not isinstance(tup[1], int) \ - or not isinstance(tup[2], bool) \ - or not isinstance(tup[3], bool): + if not (isinstance(tup, tuple) and len(tup) == 4 + and font_is_installed(tup[0]) + and isinstance(tup[1], int) + and isinstance(tup[2], bool) + and isinstance(tup[3], bool)): return None font = QtGui.QFont() family, size, italic, bold = tup @@ -186,7 +182,7 @@ def __init__(self, value, parent=None): # Font size self.size = QtWidgets.QComboBox(parent) self.size.setEditable(True) - sizelist = list(xrange(6, 12)) + list(xrange(12, 30, 2)) + [36, 48, 72] + sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72] size = font.pointSize() if size not in sizelist: sizelist.append(size) @@ -224,8 +220,7 @@ class FormWidget(QtWidgets.QWidget): update_buttons = QtCore.Signal() def __init__(self, data, comment="", parent=None): QtWidgets.QWidget.__init__(self, parent) - from copy import deepcopy - self.data = deepcopy(data) + self.data = copy.deepcopy(data) self.widgets = [] self.formlayout = QtWidgets.QFormLayout(self) if comment: @@ -281,8 +276,9 @@ def setup(self): elif selindex in keys: selindex = keys.index(selindex) elif not isinstance(selindex, int): - print("Warning: '%s' index is invalid (label: " - "%s, value: %s)" % (selindex, label, value), file=STDERR) + warnings.warn( + "index '%s' is invalid (label: %s, value: %s)" % + (selindex, label, value)) selindex = 0 field.setCurrentIndex(selindex) elif isinstance(value, bool): @@ -428,8 +424,8 @@ def __init__(self, data, title="", comment="", self.formwidget.setup() # Button box - self.bbox = bbox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok - | QtWidgets.QDialogButtonBox.Cancel) + self.bbox = bbox = QtWidgets.QDialogButtonBox( + QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) self.formwidget.update_buttons.connect(self.update_buttons) if self.apply_callback is not None: apply_btn = bbox.addButton(QtWidgets.QDialogButtonBox.Apply) @@ -454,7 +450,8 @@ def update_buttons(self): for field in self.float_fields: if not is_edit_valid(field): valid = False - for btn_type in (QtWidgets.QDialogButtonBox.Ok, QtWidgets.QDialogButtonBox.Apply): + for btn_type in (QtWidgets.QDialogButtonBox.Ok, + QtWidgets.QDialogButtonBox.Apply): btn = self.bbox.button(btn_type) if btn is not None: btn.setEnabled(valid) From 87ab70a938f242a48f06bc1fb3cd4d2652a9d715 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 4 May 2016 19:11:29 -0700 Subject: [PATCH 2/2] Qt editor alpha handling. --- .../backends/qt_editor/figureoptions.py | 28 +++++++++------- .../backends/qt_editor/formlayout.py | 32 +++++++++---------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/lib/matplotlib/backends/qt_editor/figureoptions.py b/lib/matplotlib/backends/qt_editor/figureoptions.py index 5094a3045255..063af6820220 100644 --- a/lib/matplotlib/backends/qt_editor/figureoptions.py +++ b/lib/matplotlib/backends/qt_editor/figureoptions.py @@ -15,17 +15,17 @@ import os.path as osp import re +import matplotlib +from matplotlib import cm, markers, colors as mcolors import matplotlib.backends.qt_editor.formlayout as formlayout from matplotlib.backends.qt_compat import QtGui -from matplotlib import cm, markers -from matplotlib.colors import colorConverter, rgb2hex def get_icon(name): - import matplotlib basedir = osp.join(matplotlib.rcParams['datapath'], 'images') return QtGui.QIcon(osp.join(basedir, name)) + LINESTYLES = {'-': 'Solid', '--': 'Dashed', '-.': 'DashDot', @@ -114,23 +114,25 @@ def prepare_data(d, init): curvelabels = sorted(linedict, key=cmp_key) for label in curvelabels: line = linedict[label] - color = rgb2hex(colorConverter.to_rgb(line.get_color())) - ec = rgb2hex(colorConverter.to_rgb(line.get_markeredgecolor())) - fc = rgb2hex(colorConverter.to_rgb(line.get_markerfacecolor())) + color = mcolors.to_hex( + mcolors.to_rgba(line.get_color(), line.get_alpha()), + keep_alpha=True) + ec = mcolors.to_hex(line.get_markeredgecolor(), keep_alpha=True) + fc = mcolors.to_hex(line.get_markerfacecolor(), keep_alpha=True) curvedata = [ ('Label', label), sep, (None, 'Line'), - ('Line Style', prepare_data(LINESTYLES, line.get_linestyle())), - ('Draw Style', prepare_data(DRAWSTYLES, line.get_drawstyle())), + ('Line style', prepare_data(LINESTYLES, line.get_linestyle())), + ('Draw style', prepare_data(DRAWSTYLES, line.get_drawstyle())), ('Width', line.get_linewidth()), - ('Color', color), + ('Color (RGBA)', color), sep, (None, 'Marker'), ('Style', prepare_data(MARKERS, line.get_marker())), ('Size', line.get_markersize()), - ('Facecolor', fc), - ('Edgecolor', ec)] + ('Face color (RGBA)', fc), + ('Edge color (RGBA)', ec)] curves.append([curvedata, label, ""]) # Is there a curve displayed? has_curve = bool(curves) @@ -206,7 +208,9 @@ def apply_callback(data): line.set_linestyle(linestyle) line.set_drawstyle(drawstyle) line.set_linewidth(linewidth) - line.set_color(color) + rgba = mcolors.to_rgba(color) + line.set_color(rgba[:3]) + line.set_alpha(rgba[-1]) if marker is not 'none': line.set_marker(marker) line.set_markersize(markersize) diff --git a/lib/matplotlib/backends/qt_editor/formlayout.py b/lib/matplotlib/backends/qt_editor/formlayout.py index 34395a5f1e33..00a1a03a36ee 100644 --- a/lib/matplotlib/backends/qt_editor/formlayout.py +++ b/lib/matplotlib/backends/qt_editor/formlayout.py @@ -46,13 +46,13 @@ DEBUG = False -import six - import copy import datetime import warnings -from matplotlib.colors import colorConverter, is_color_like, rgb2hex +import six + +from matplotlib import colors as mcolors from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore @@ -74,7 +74,8 @@ def __init__(self, parent=None): def choose_color(self): color = QtWidgets.QColorDialog.getColor( - self._color, self.parentWidget(), '') + self._color, self.parentWidget(), "", + QtWidgets.QColorDialog.ShowAlphaChannel) if color.isValid(): self.set_color(color) @@ -93,22 +94,16 @@ def set_color(self, color): color = QtCore.Property(QtGui.QColor, get_color, set_color) -def col2hex(color): - """Convert matplotlib color to hex before passing to Qt""" - return rgb2hex(colorConverter.to_rgb(color)) - - def to_qcolor(color): """Create a QColor from a matplotlib color""" qcolor = QtGui.QColor() - color = str(color) try: - color = col2hex(color) + rgba = mcolors.to_rgba(color) except ValueError: warnings.warn('Ignoring invalid color %r' % color) return qcolor # return invalid QColor - qcolor.setNamedColor(color) # set using hex color - return qcolor # return valid QColor + qcolor.setRgbF(*rgba) + return qcolor class ColorLayout(QtWidgets.QHBoxLayout): @@ -116,7 +111,8 @@ class ColorLayout(QtWidgets.QHBoxLayout): def __init__(self, color, parent=None): QtWidgets.QHBoxLayout.__init__(self) assert isinstance(color, QtGui.QColor) - self.lineedit = QtWidgets.QLineEdit(color.name(), parent) + self.lineedit = QtWidgets.QLineEdit( + mcolors.to_hex(color.getRgbF(), keep_alpha=True), parent) self.lineedit.editingFinished.connect(self.update_color) self.addWidget(self.lineedit) self.colorbtn = ColorButton(parent) @@ -130,7 +126,7 @@ def update_color(self): self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid() def update_text(self, color): - self.lineedit.setText(color.name()) + self.lineedit.setText(mcolors.to_hex(color.getRgbF(), keep_alpha=True)) def text(self): return self.lineedit.text() @@ -256,7 +252,8 @@ def setup(self): continue elif tuple_to_qfont(value) is not None: field = FontLayout(value, self) - elif label.lower() not in BLACKLIST and is_color_like(value): + elif (label.lower() not in BLACKLIST + and mcolors.is_color_like(value)): field = ColorLayout(to_qcolor(value), self) elif isinstance(value, six.string_types): field = QtWidgets.QLineEdit(value, self) @@ -319,7 +316,8 @@ def get(self): continue elif tuple_to_qfont(value) is not None: value = field.get_font() - elif isinstance(value, six.string_types) or is_color_like(value): + elif (isinstance(value, six.string_types) + or mcolors.is_color_like(value)): value = six.text_type(field.text()) elif isinstance(value, (list, tuple)): index = int(field.currentIndex())