import re from PyQt6.QtCore import QSize, Qt, QRect from PyQt6.QtGui import QColor, QPainter, QPixmap, QIcon, QBrush, QPen, QPaintEngine from PyQt6.QtWidgets import QWidget, QHBoxLayout, QPushButton, QColorDialog, QSizePolicy, QComboBox class ColorButton(QWidget): def __init__(self, color: str): super(QWidget, self).__init__() self.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) self.layout = QHBoxLayout(self) self.color = color colors = ['aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'] colors = { self.tr('Hot Pink'): 'ffaebc', self.tr('Light Coral'): 'f08080', self.tr('Red'): 'cc0000', self.tr('Orange'): 'fcaf3e', self.tr('Dark Orange'): 'ce5c00', self.tr('Yellow'): 'fce94f', self.tr('Dark Yellow'): 'c4a000', self.tr('Mint'): 'b4f8c8', self.tr('Green'): '8ae234', self.tr('Dark Green'): '439a06', self.tr('Tiffany Blue'): 'a0e7e5', self.tr('Blue'): '729fcf', self.tr('Dark Blue'): '3465a4', self.tr('Purple'): 'ad7fa8', self.tr('Dark Purple'): '5c3566', self.tr('Brown'): 'e9b96e', self.tr('Dark Brown'): 'c17d11', self.tr('Grey'): 'd3d7cf', self.tr('Dark Grey'): '888a85', self.tr('Brewer Light Blue'): 'ece7f2', self.tr('Brewer Blue'): 'a6bddb', self.tr('Brewer Dark Blue'): '2b8cbe', self.tr('Brewer Light Red'): 'fee8c8', self.tr('Brewer Red'): 'fdbb84', self.tr('Brewer Dark Red'): 'e34a33', } self.color_drop_down = QComboBox() self.layout.addWidget(self.color_drop_down) self.color_drop_down.addItem("transparent", "None") for color_name in colors.keys(): color_value = colors[color_name] self.color_drop_down.addItem(QIcon(self._color_pixmap(color_value)), color_name, color_value) self.color_drop_down.currentIndexChanged.connect(self._color_selected) self.btn_color_picker = QPushButton(self.tr("custom")) self.layout.addWidget(self.btn_color_picker) self.btn_color_picker.pressed.connect(self._update_color) self.btn_color_picker.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)) def _color_selected(self, index: int): self.color = self.color_drop_down.currentData() print(self.color) def set_color(self, color: str): self.color = color for index in range(0, self.color_drop_down.count()): item_value = self.color_drop_down.itemData(index) if item_value == color: self.color_drop_down.setCurrentIndex(index) return # color not yet present -> add it self.color_drop_down.addItem(QIcon(self._color_pixmap(color)), color, color) self.color_drop_down.setCurrentIndex(self.color_drop_down.count() - 1) def _update_color(self): new_color = QColorDialog.getColor(self._to_qcolor(self.color)) if new_color.isValid(): color = self._to_hex(new_color) self.set_color(color) @staticmethod def _is_hex_color(color: str): return re.match("[0-9a-f]{6}", color, flags=re.IGNORECASE) def _color_pixmap(self, color: str) -> QPixmap: pixmap = QPixmap(40, 40) qcolor = self._to_qcolor(color) pixmap.fill((qcolor)) return pixmap def _to_qcolor(self, color: str): if self._is_hex_color(color): red = int(color[0:2], 16) green = int(color[2:4], 16) blue = int(color[4:6], 16) return QColor(red, green, blue) elif color in QColor().colorNames(): return QColor(color) return QColor(255, 255, 255) def _to_hex(self, color: QColor) -> str: red = "{0:0{1}x}".format(color.red(), 2) green = "{0:0{1}x}".format(color.green(), 2) blue = "{0:0{1}x}".format(color.blue(), 2) return red + green + blue