# -*- coding: utf-8 -*- # # Copyright © Spyder Project Contributors # Licensed under the terms of the MIT License # (see spyder/__init__.py for details) # Third party imports from qtpy.QtCore import Property, QSize, Signal, Slot from qtpy.QtGui import QColor, QIcon, QPixmap from qtpy.QtWidgets import QColorDialog, QHBoxLayout, QLineEdit, QToolButton # Local imports from spyder.py3compat import is_text_string class ColorButton(QToolButton): """ Color choosing push button """ colorChanged = Signal(QColor) def __init__(self, parent=None): QToolButton.__init__(self, parent) self.setFixedSize(20, 20) self.setIconSize(QSize(12, 12)) self.clicked.connect(self.choose_color) self._color = QColor() def choose_color(self): color = QColorDialog.getColor(self._color, self.parentWidget(), 'Select Color', QColorDialog.ShowAlphaChannel) if color.isValid(): self.set_color(color) def get_color(self): return self._color @Slot(QColor) def set_color(self, color): if color != self._color: self._color = color self.colorChanged.emit(self._color) pixmap = QPixmap(self.iconSize()) pixmap.fill(color) self.setIcon(QIcon(pixmap)) color = Property("QColor", get_color, set_color) def text_to_qcolor(text): """ Create a QColor from specified string Avoid warning from Qt when an invalid QColor is instantiated """ color = QColor() text = str(text) if not is_text_string(text): return color if text.startswith('#') and len(text)==7: correct = '#0123456789abcdef' for char in text: if char.lower() not in correct: return color elif text not in list(QColor.colorNames()): return color color.setNamedColor(text) return color class ColorLayout(QHBoxLayout): """Color-specialized QLineEdit layout""" def __init__(self, color, parent=None): QHBoxLayout.__init__(self) assert isinstance(color, QColor) self.lineedit = QLineEdit(color.name(), parent) fm = self.lineedit.fontMetrics() self.lineedit.setMinimumWidth(int(fm.width(color.name()) * 1.2)) self.lineedit.textChanged.connect(self.update_color) self.addWidget(self.lineedit) self.colorbtn = ColorButton(parent) self.colorbtn.color = color self.colorbtn.colorChanged.connect(self.update_text) self.addWidget(self.colorbtn) def update_color(self, text): color = text_to_qcolor(text) if color.isValid(): self.colorbtn.color = color def update_text(self, color): self.lineedit.setText(color.name()) def text(self): return self.lineedit.text()