1from PyQt5.QtCore import Qt, QPointF 2from PyQt5.QtGui import QColor, QPen, QTransform 3from PyQt5.QtWidgets import QGraphicsRectItem 4 5 6class Selection(QGraphicsRectItem): 7 def __init__(self, *args, fillcolor, opacity, parent=None): 8 if len(args) == 0: 9 super().__init__(parent) 10 elif len(args) == 1: 11 super().__init__(args[0], parent) 12 elif len(args) == 4: 13 x0, y0, w, h = args 14 super().__init__(x0, y0, w, h, parent) 15 16 self.finished = False 17 self.selected_edge = None # type: int 18 self.resizing = False 19 20 self.setBrush(fillcolor) 21 self.setPen(QPen(QColor(Qt.transparent), 0)) 22 self.setOpacity(opacity) 23 24 @property 25 def is_empty(self) -> bool: 26 raise NotImplementedError("Overwrite in subclass") 27 28 @property 29 def width(self): 30 return self.rect().width() 31 32 @width.setter 33 def width(self, value): 34 if value == self.width: 35 return 36 37 r = self.rect() 38 r.setWidth(value) 39 self.setRect(r) 40 41 @property 42 def height(self): 43 return self.rect().height() 44 45 @height.setter 46 def height(self, value): 47 if value == self.height: 48 return 49 50 r = self.rect() 51 r.setHeight(value) 52 self.setRect(r) 53 54 @property 55 def x(self): 56 return self.rect().x() 57 58 def setX(self, p_float): 59 if p_float == self.x: 60 return 61 62 r = self.rect() 63 r.setX(p_float) 64 self.setRect(r) 65 66 @property 67 def y(self): 68 return self.rect().y() 69 70 def setY(self, p_float): 71 if p_float == self.y: 72 return 73 74 r = self.rect() 75 r.setY(p_float) 76 self.setRect(r) 77 78 @property 79 def start(self): 80 raise NotImplementedError("Overwrite in subclass") 81 82 @start.setter 83 def start(self, value): 84 raise NotImplementedError("Overwrite in subclass") 85 86 @property 87 def end(self): 88 raise NotImplementedError("Overwrite in subclass") 89 90 @end.setter 91 def end(self, value): 92 raise NotImplementedError("Overwrite in subclass") 93 94 def _get_selected_edge(self, pos: QPointF, transform: QTransform, horizontal_selection: bool): 95 x1, x2 = self.x, self.x + self.width 96 y1, y2 = self.y, self.y + self.height 97 x, y = pos.x(), pos.y() 98 99 spacing = 5 100 spacing /= transform.m11() if horizontal_selection else transform.m22() 101 102 if horizontal_selection: 103 x1a, x1b = x1 - spacing, x1 + spacing 104 y1a, y1b = y1, y2 105 x2a, x2b = x2 - spacing, x2 + spacing 106 y2a, y2b = y1, y2 107 else: 108 x1a, x1b, x2a, x2b = x1, x2, x1, x2 109 y1a, y1b = min(y1 - spacing, y1 + spacing), max(y1 - spacing, y1 + spacing) 110 y2a, y2b = min(y2 - spacing, y2 + spacing), max(y2 - spacing, y2 + spacing) 111 112 if x1a < x < x1b and y1a < y < y1b: 113 self.selected_edge = 0 114 return 0 115 116 if x2a < x < x2b and y2a < y < y2b: 117 self.selected_edge = 1 118 return 1 119 120 self.selected_edge = None 121 return None 122 123 def clear(self): 124 self.resizing = False 125 self.selected_edge = None 126 self.finished = False 127