src/eric7/Snapshot/SnapshotFreehandGrabber.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
7 Module implementing a grabber widget for a freehand snapshot region. 7 Module implementing a grabber widget for a freehand snapshot region.
8 """ 8 """
9 9
10 from PyQt6.QtCore import pyqtSignal, Qt, QRect, QPoint, QTimer, QLocale 10 from PyQt6.QtCore import pyqtSignal, Qt, QRect, QPoint, QTimer, QLocale
11 from PyQt6.QtGui import ( 11 from PyQt6.QtGui import (
12 QPixmap, QColor, QRegion, QPainter, QPalette, QPolygon, QPen, QBrush, 12 QPixmap,
13 QPaintEngine, QGuiApplication, QCursor 13 QColor,
14 QRegion,
15 QPainter,
16 QPalette,
17 QPolygon,
18 QPen,
19 QBrush,
20 QPaintEngine,
21 QGuiApplication,
22 QCursor,
14 ) 23 )
15 from PyQt6.QtWidgets import QWidget, QToolTip 24 from PyQt6.QtWidgets import QWidget, QToolTip
16 25
17 import Globals 26 import Globals
18 27
19 28
20 def drawPolygon(painter, polygon, outline, fill=None): 29 def drawPolygon(painter, polygon, outline, fill=None):
21 """ 30 """
22 Module function to draw a polygon with the given parameters. 31 Module function to draw a polygon with the given parameters.
23 32
24 @param painter reference to the painter to be used (QPainter) 33 @param painter reference to the painter to be used (QPainter)
25 @param polygon polygon to be drawn (QPolygon) 34 @param polygon polygon to be drawn (QPolygon)
26 @param outline color of the outline (QColor) 35 @param outline color of the outline (QColor)
27 @param fill fill color (QColor) 36 @param fill fill color (QColor)
28 """ 37 """
29 clip = QRegion(polygon) 38 clip = QRegion(polygon)
30 clip -= QRegion(polygon) 39 clip -= QRegion(polygon)
31 pen = QPen(outline, 1, Qt.PenStyle.SolidLine, Qt.PenCapStyle.SquareCap, 40 pen = QPen(
32 Qt.PenJoinStyle.BevelJoin) 41 outline,
33 42 1,
43 Qt.PenStyle.SolidLine,
44 Qt.PenCapStyle.SquareCap,
45 Qt.PenJoinStyle.BevelJoin,
46 )
47
34 painter.save() 48 painter.save()
35 painter.setClipRegion(clip) 49 painter.setClipRegion(clip)
36 painter.setPen(pen) 50 painter.setPen(pen)
37 painter.drawPolygon(QPolygon(polygon)) 51 painter.drawPolygon(QPolygon(polygon))
38 if fill and fill.isValid(): 52 if fill and fill.isValid():
43 57
44 58
45 class SnapshotFreehandGrabber(QWidget): 59 class SnapshotFreehandGrabber(QWidget):
46 """ 60 """
47 Class implementing a grabber widget for a freehand snapshot region. 61 Class implementing a grabber widget for a freehand snapshot region.
48 62
49 @signal grabbed(QPixmap) emitted after the region was grabbed 63 @signal grabbed(QPixmap) emitted after the region was grabbed
50 """ 64 """
65
51 grabbed = pyqtSignal(QPixmap) 66 grabbed = pyqtSignal(QPixmap)
52 67
53 def __init__(self): 68 def __init__(self):
54 """ 69 """
55 Constructor 70 Constructor
56 """ 71 """
57 super().__init__( 72 super().__init__(
58 None, 73 None,
59 Qt.WindowType.X11BypassWindowManagerHint | 74 Qt.WindowType.X11BypassWindowManagerHint
60 Qt.WindowType.WindowStaysOnTopHint | 75 | Qt.WindowType.WindowStaysOnTopHint
61 Qt.WindowType.FramelessWindowHint | 76 | Qt.WindowType.FramelessWindowHint
62 Qt.WindowType.Tool 77 | Qt.WindowType.Tool,
63 ) 78 )
64 79
65 self.__selection = QPolygon() 80 self.__selection = QPolygon()
66 self.__mouseDown = False 81 self.__mouseDown = False
67 self.__newSelection = False 82 self.__newSelection = False
68 self.__handleSize = 10 83 self.__handleSize = 10
69 self.__showHelp = True 84 self.__showHelp = True
70 self.__grabbing = False 85 self.__grabbing = False
71 self.__dragStartPoint = QPoint() 86 self.__dragStartPoint = QPoint()
72 self.__selectionBeforeDrag = QPolygon() 87 self.__selectionBeforeDrag = QPolygon()
73 self.__locale = QLocale() 88 self.__locale = QLocale()
74 89
75 self.__helpTextRect = QRect() 90 self.__helpTextRect = QRect()
76 self.__helpText = self.tr( 91 self.__helpText = self.tr(
77 "Select a region using the mouse. To take the snapshot," 92 "Select a region using the mouse. To take the snapshot,"
78 " press the Enter key or double click. Press Esc to quit.") 93 " press the Enter key or double click. Press Esc to quit."
79 94 )
95
80 self.__pixmap = QPixmap() 96 self.__pixmap = QPixmap()
81 self.__pBefore = QPoint() 97 self.__pBefore = QPoint()
82 98
83 self.setMouseTracking(True) 99 self.setMouseTracking(True)
84 100
85 QTimer.singleShot(200, self.__initialize) 101 QTimer.singleShot(200, self.__initialize)
86 102
87 def __initialize(self): 103 def __initialize(self):
88 """ 104 """
89 Private slot to initialize the rest of the widget. 105 Private slot to initialize the rest of the widget.
90 """ 106 """
91 if Globals.isMacPlatform(): 107 if Globals.isMacPlatform():
92 # macOS variant 108 # macOS variant
93 screen = QGuiApplication.screenAt(QCursor.pos()) 109 screen = QGuiApplication.screenAt(QCursor.pos())
94 geom = screen.geometry() 110 geom = screen.geometry()
95 self.__pixmap = screen.grabWindow( 111 self.__pixmap = screen.grabWindow(
96 0, geom.x(), geom.y(), geom.width(), geom.height()) 112 0, geom.x(), geom.y(), geom.width(), geom.height()
113 )
97 else: 114 else:
98 # Linux variant 115 # Linux variant
99 # Windows variant 116 # Windows variant
100 screen = QGuiApplication.screens()[0] 117 screen = QGuiApplication.screens()[0]
101 geom = screen.availableVirtualGeometry() 118 geom = screen.availableVirtualGeometry()
102 self.__pixmap = screen.grabWindow( 119 self.__pixmap = screen.grabWindow(
103 0, geom.x(), geom.y(), geom.width(), geom.height()) 120 0, geom.x(), geom.y(), geom.width(), geom.height()
121 )
104 self.resize(self.__pixmap.size()) 122 self.resize(self.__pixmap.size())
105 self.move(geom.x(), geom.y()) 123 self.move(geom.x(), geom.y())
106 self.setCursor(Qt.CursorShape.CrossCursor) 124 self.setCursor(Qt.CursorShape.CrossCursor)
107 self.show() 125 self.show()
108 126
109 self.grabMouse() 127 self.grabMouse()
110 self.grabKeyboard() 128 self.grabKeyboard()
111 self.activateWindow() 129 self.activateWindow()
112 130
113 def paintEvent(self, evt): 131 def paintEvent(self, evt):
114 """ 132 """
115 Protected method handling paint events. 133 Protected method handling paint events.
116 134
117 @param evt paint event (QPaintEvent) 135 @param evt paint event (QPaintEvent)
118 """ 136 """
119 if self.__grabbing: # grabWindow() should just get the background 137 if self.__grabbing: # grabWindow() should just get the background
120 return 138 return
121 139
122 painter = QPainter(self) 140 painter = QPainter(self)
123 pal = QPalette(QToolTip.palette()) 141 pal = QPalette(QToolTip.palette())
124 font = QToolTip.font() 142 font = QToolTip.font()
125 143
126 handleColor = pal.color(QPalette.ColorGroup.Active, 144 handleColor = pal.color(
127 QPalette.ColorRole.Highlight) 145 QPalette.ColorGroup.Active, QPalette.ColorRole.Highlight
146 )
128 handleColor.setAlpha(160) 147 handleColor.setAlpha(160)
129 overlayColor = QColor(0, 0, 0, 160) 148 overlayColor = QColor(0, 0, 0, 160)
130 textColor = pal.color(QPalette.ColorGroup.Active, 149 textColor = pal.color(QPalette.ColorGroup.Active, QPalette.ColorRole.Text)
131 QPalette.ColorRole.Text) 150 textBackgroundColor = pal.color(
132 textBackgroundColor = pal.color(QPalette.ColorGroup.Active, 151 QPalette.ColorGroup.Active, QPalette.ColorRole.Base
133 QPalette.ColorRole.Base) 152 )
134 painter.drawPixmap(0, 0, self.__pixmap) 153 painter.drawPixmap(0, 0, self.__pixmap)
135 painter.setFont(font) 154 painter.setFont(font)
136 155
137 pol = QPolygon(self.__selection) 156 pol = QPolygon(self.__selection)
138 if not self.__selection.boundingRect().isNull(): 157 if not self.__selection.boundingRect().isNull():
139 # Draw outline around selection. 158 # Draw outline around selection.
140 # Important: the 1px-wide outline is *also* part of the 159 # Important: the 1px-wide outline is *also* part of the
141 # captured free-region 160 # captured free-region
142 pen = QPen(handleColor, 1, Qt.PenStyle.SolidLine, 161 pen = QPen(
143 Qt.PenCapStyle.SquareCap, Qt.PenJoinStyle.BevelJoin) 162 handleColor,
163 1,
164 Qt.PenStyle.SolidLine,
165 Qt.PenCapStyle.SquareCap,
166 Qt.PenJoinStyle.BevelJoin,
167 )
144 painter.setPen(pen) 168 painter.setPen(pen)
145 painter.drawPolygon(pol) 169 painter.drawPolygon(pol)
146 170
147 # Draw the grey area around the selection. 171 # Draw the grey area around the selection.
148 grey = QRegion(self.rect()) 172 grey = QRegion(self.rect())
149 grey -= QRegion(pol) 173 grey -= QRegion(pol)
150 painter.setClipRegion(grey) 174 painter.setClipRegion(grey)
151 painter.setPen(Qt.PenStyle.NoPen) 175 painter.setPen(Qt.PenStyle.NoPen)
152 painter.setBrush(overlayColor) 176 painter.setBrush(overlayColor)
153 painter.drawRect(self.rect()) 177 painter.drawRect(self.rect())
154 painter.setClipRect(self.rect()) 178 painter.setClipRect(self.rect())
155 drawPolygon(painter, pol, handleColor) 179 drawPolygon(painter, pol, handleColor)
156 180
157 if self.__showHelp: 181 if self.__showHelp:
158 painter.setPen(textColor) 182 painter.setPen(textColor)
159 painter.setBrush(textBackgroundColor) 183 painter.setBrush(textBackgroundColor)
160 self.__helpTextRect = painter.boundingRect( 184 self.__helpTextRect = painter.boundingRect(
161 self.rect().adjusted(2, 2, -2, -2), 185 self.rect().adjusted(2, 2, -2, -2),
162 Qt.TextFlag.TextWordWrap, self.__helpText).translated(0, 0) 186 Qt.TextFlag.TextWordWrap,
187 self.__helpText,
188 ).translated(0, 0)
163 self.__helpTextRect.adjust(-2, -2, 4, 2) 189 self.__helpTextRect.adjust(-2, -2, 4, 2)
164 drawPolygon(painter, self.__helpTextRect, textColor, 190 drawPolygon(painter, self.__helpTextRect, textColor, textBackgroundColor)
165 textBackgroundColor)
166 painter.drawText( 191 painter.drawText(
167 self.__helpTextRect.adjusted(3, 3, -3, -3), 192 self.__helpTextRect.adjusted(3, 3, -3, -3),
168 Qt.TextFlag.TextWordWrap, self.__helpText) 193 Qt.TextFlag.TextWordWrap,
169 194 self.__helpText,
195 )
196
170 if self.__selection.isEmpty(): 197 if self.__selection.isEmpty():
171 return 198 return
172 199
173 # The grabbed region is everything which is covered by the drawn 200 # The grabbed region is everything which is covered by the drawn
174 # rectangles (border included). This means that there is no 0px 201 # rectangles (border included). This means that there is no 0px
175 # selection, since a 0px wide rectangle will always be drawn as a line. 202 # selection, since a 0px wide rectangle will always be drawn as a line.
176 boundingRect = self.__selection.boundingRect() 203 boundingRect = self.__selection.boundingRect()
177 txt = "{0}, {1} ({2} x {3})".format( 204 txt = "{0}, {1} ({2} x {3})".format(
178 self.__locale.toString(boundingRect.x()), 205 self.__locale.toString(boundingRect.x()),
179 self.__locale.toString(boundingRect.y()), 206 self.__locale.toString(boundingRect.y()),
180 self.__locale.toString(boundingRect.width()), 207 self.__locale.toString(boundingRect.width()),
181 self.__locale.toString(boundingRect.height()) 208 self.__locale.toString(boundingRect.height()),
182 ) 209 )
183 textRect = painter.boundingRect(self.rect(), 210 textRect = painter.boundingRect(self.rect(), Qt.AlignmentFlag.AlignLeft, txt)
184 Qt.AlignmentFlag.AlignLeft, txt)
185 boundingRect = textRect.adjusted(-4, 0, 0, 0) 211 boundingRect = textRect.adjusted(-4, 0, 0, 0)
186 212
187 polBoundingRect = pol.boundingRect() 213 polBoundingRect = pol.boundingRect()
188 if ( 214 if (
189 (textRect.width() < 215 (textRect.width() < polBoundingRect.width() - 2 * self.__handleSize)
190 polBoundingRect.width() - 2 * self.__handleSize) and 216 and (textRect.height() < polBoundingRect.height() - 2 * self.__handleSize)
191 (textRect.height() < 217 and polBoundingRect.width() > 100
192 polBoundingRect.height() - 2 * self.__handleSize) and 218 and polBoundingRect.height() > 100
193 polBoundingRect.width() > 100 and
194 polBoundingRect.height() > 100
195 ): 219 ):
196 # center, unsuitable for small selections 220 # center, unsuitable for small selections
197 boundingRect.moveCenter(polBoundingRect.center()) 221 boundingRect.moveCenter(polBoundingRect.center())
198 textRect.moveCenter(polBoundingRect.center()) 222 textRect.moveCenter(polBoundingRect.center())
199 elif ( 223 elif (
200 polBoundingRect.y() - 3 > textRect.height() and 224 polBoundingRect.y() - 3 > textRect.height()
201 polBoundingRect.x() + textRect.width() < self.rect().width() 225 and polBoundingRect.x() + textRect.width() < self.rect().width()
202 ): 226 ):
203 # on top, left aligned 227 # on top, left aligned
204 boundingRect.moveBottomLeft( 228 boundingRect.moveBottomLeft(
205 QPoint(polBoundingRect.x(), polBoundingRect.y() - 3)) 229 QPoint(polBoundingRect.x(), polBoundingRect.y() - 3)
230 )
206 textRect.moveBottomLeft( 231 textRect.moveBottomLeft(
207 QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3)) 232 QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3)
233 )
208 elif polBoundingRect.x() - 3 > textRect.width(): 234 elif polBoundingRect.x() - 3 > textRect.width():
209 # left, top aligned 235 # left, top aligned
210 boundingRect.moveTopRight( 236 boundingRect.moveTopRight(
211 QPoint(polBoundingRect.x() - 3, polBoundingRect.y())) 237 QPoint(polBoundingRect.x() - 3, polBoundingRect.y())
212 textRect.moveTopRight( 238 )
213 QPoint(polBoundingRect.x() - 5, polBoundingRect.y())) 239 textRect.moveTopRight(QPoint(polBoundingRect.x() - 5, polBoundingRect.y()))
214 elif ( 240 elif (
215 (polBoundingRect.bottom() + 3 + textRect.height() < 241 polBoundingRect.bottom() + 3 + textRect.height() < self.rect().bottom()
216 self.rect().bottom()) and 242 ) and polBoundingRect.right() > textRect.width():
217 polBoundingRect.right() > textRect.width()
218 ):
219 # at bottom, right aligned 243 # at bottom, right aligned
220 boundingRect.moveTopRight( 244 boundingRect.moveTopRight(
221 QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3)) 245 QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3)
246 )
222 textRect.moveTopRight( 247 textRect.moveTopRight(
223 QPoint(polBoundingRect.right() - 2, 248 QPoint(polBoundingRect.right() - 2, polBoundingRect.bottom() + 3)
224 polBoundingRect.bottom() + 3)) 249 )
225 elif ( 250 elif polBoundingRect.right() + textRect.width() + 3 < self.rect().width():
226 polBoundingRect.right() + textRect.width() + 3 <
227 self.rect().width()
228 ):
229 # right, bottom aligned 251 # right, bottom aligned
230 boundingRect.moveBottomLeft( 252 boundingRect.moveBottomLeft(
231 QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom())) 253 QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom())
254 )
232 textRect.moveBottomLeft( 255 textRect.moveBottomLeft(
233 QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom())) 256 QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom())
234 257 )
258
235 # If the above didn't catch it, you are running on a very 259 # If the above didn't catch it, you are running on a very
236 # tiny screen... 260 # tiny screen...
237 drawPolygon(painter, boundingRect, textColor, textBackgroundColor) 261 drawPolygon(painter, boundingRect, textColor, textBackgroundColor)
238 painter.drawText(textRect, Qt.AlignmentFlag.AlignHCenter, txt) 262 painter.drawText(textRect, Qt.AlignmentFlag.AlignHCenter, txt)
239 263
240 if ( 264 if (
241 (polBoundingRect.height() > self.__handleSize * 2 and 265 polBoundingRect.height() > self.__handleSize * 2
242 polBoundingRect.width() > self.__handleSize * 2) or 266 and polBoundingRect.width() > self.__handleSize * 2
243 not self.__mouseDown 267 ) or not self.__mouseDown:
244 ):
245 painter.setBrush(Qt.GlobalColor.transparent) 268 painter.setBrush(Qt.GlobalColor.transparent)
246 painter.setClipRegion(QRegion(pol)) 269 painter.setClipRegion(QRegion(pol))
247 painter.drawPolygon(QPolygon(self.rect())) 270 painter.drawPolygon(QPolygon(self.rect()))
248 271
249 def mousePressEvent(self, evt): 272 def mousePressEvent(self, evt):
250 """ 273 """
251 Protected method to handle mouse button presses. 274 Protected method to handle mouse button presses.
252 275
253 @param evt mouse press event (QMouseEvent) 276 @param evt mouse press event (QMouseEvent)
254 """ 277 """
255 self.__pBefore = evt.position().toPoint() 278 self.__pBefore = evt.position().toPoint()
256 279
257 self.__showHelp = not self.__helpTextRect.contains( 280 self.__showHelp = not self.__helpTextRect.contains(evt.position().toPoint())
258 evt.position().toPoint())
259 if evt.button() == Qt.MouseButton.LeftButton: 281 if evt.button() == Qt.MouseButton.LeftButton:
260 self.__mouseDown = True 282 self.__mouseDown = True
261 self.__dragStartPoint = evt.position().toPoint() 283 self.__dragStartPoint = evt.position().toPoint()
262 self.__selectionBeforeDrag = QPolygon(self.__selection) 284 self.__selectionBeforeDrag = QPolygon(self.__selection)
263 if not self.__selection.containsPoint(evt.position().toPoint(), 285 if not self.__selection.containsPoint(
264 Qt.FillRule.WindingFill): 286 evt.position().toPoint(), Qt.FillRule.WindingFill
287 ):
265 self.__newSelection = True 288 self.__newSelection = True
266 self.__selection = QPolygon() 289 self.__selection = QPolygon()
267 else: 290 else:
268 self.setCursor(Qt.CursorShape.ClosedHandCursor) 291 self.setCursor(Qt.CursorShape.ClosedHandCursor)
269 elif evt.button() == Qt.MouseButton.RightButton: 292 elif evt.button() == Qt.MouseButton.RightButton:
270 self.__newSelection = False 293 self.__newSelection = False
271 self.__selection = QPolygon() 294 self.__selection = QPolygon()
272 self.setCursor(Qt.CursorShape.CrossCursor) 295 self.setCursor(Qt.CursorShape.CrossCursor)
273 self.update() 296 self.update()
274 297
275 def mouseMoveEvent(self, evt): 298 def mouseMoveEvent(self, evt):
276 """ 299 """
277 Protected method to handle mouse movements. 300 Protected method to handle mouse movements.
278 301
279 @param evt mouse move event (QMouseEvent) 302 @param evt mouse move event (QMouseEvent)
280 """ 303 """
281 shouldShowHelp = not self.__helpTextRect.contains( 304 shouldShowHelp = not self.__helpTextRect.contains(evt.position().toPoint())
282 evt.position().toPoint())
283 if shouldShowHelp != self.__showHelp: 305 if shouldShowHelp != self.__showHelp:
284 self.__showHelp = shouldShowHelp 306 self.__showHelp = shouldShowHelp
285 self.update() 307 self.update()
286 308
287 if self.__mouseDown: 309 if self.__mouseDown:
288 if self.__newSelection: 310 if self.__newSelection:
289 p = evt.position().toPoint() 311 p = evt.position().toPoint()
290 self.__selection.append(p) 312 self.__selection.append(p)
291 else: 313 else:
292 # moving the whole selection 314 # moving the whole selection
293 p = evt.position().toPoint() - self.__pBefore # Offset 315 p = evt.position().toPoint() - self.__pBefore # Offset
294 self.__pBefore = evt.position().toPoint() 316 self.__pBefore = evt.position().toPoint()
295 # save position for next iteration 317 # save position for next iteration
296 self.__selection.translate(p) 318 self.__selection.translate(p)
297 319
298 self.update() 320 self.update()
299 else: 321 else:
300 if self.__selection.boundingRect().isEmpty(): 322 if self.__selection.boundingRect().isEmpty():
301 return 323 return
302 324
303 if self.__selection.containsPoint(evt.position().toPoint(), 325 if self.__selection.containsPoint(
304 Qt.FillRule.WindingFill): 326 evt.position().toPoint(), Qt.FillRule.WindingFill
327 ):
305 self.setCursor(Qt.CursorShape.OpenHandCursor) 328 self.setCursor(Qt.CursorShape.OpenHandCursor)
306 else: 329 else:
307 self.setCursor(Qt.CursorShape.CrossCursor) 330 self.setCursor(Qt.CursorShape.CrossCursor)
308 331
309 def mouseReleaseEvent(self, evt): 332 def mouseReleaseEvent(self, evt):
310 """ 333 """
311 Protected method to handle mouse button releases. 334 Protected method to handle mouse button releases.
312 335
313 @param evt mouse release event (QMouseEvent) 336 @param evt mouse release event (QMouseEvent)
314 """ 337 """
315 self.__mouseDown = False 338 self.__mouseDown = False
316 self.__newSelection = False 339 self.__newSelection = False
317 if self.__selection.containsPoint(evt.position().toPoint(), 340 if self.__selection.containsPoint(
318 Qt.FillRule.WindingFill): 341 evt.position().toPoint(), Qt.FillRule.WindingFill
342 ):
319 self.setCursor(Qt.CursorShape.OpenHandCursor) 343 self.setCursor(Qt.CursorShape.OpenHandCursor)
320 self.update() 344 self.update()
321 345
322 def mouseDoubleClickEvent(self, evt): 346 def mouseDoubleClickEvent(self, evt):
323 """ 347 """
324 Protected method to handle mouse double clicks. 348 Protected method to handle mouse double clicks.
325 349
326 @param evt mouse double click event (QMouseEvent) 350 @param evt mouse double click event (QMouseEvent)
327 """ 351 """
328 self.__grabRegion() 352 self.__grabRegion()
329 353
330 def keyPressEvent(self, evt): 354 def keyPressEvent(self, evt):
331 """ 355 """
332 Protected method to handle key presses. 356 Protected method to handle key presses.
333 357
334 @param evt key press event (QKeyEvent) 358 @param evt key press event (QKeyEvent)
335 """ 359 """
336 if evt.key() == Qt.Key.Key_Escape: 360 if evt.key() == Qt.Key.Key_Escape:
337 self.grabbed.emit(QPixmap()) 361 self.grabbed.emit(QPixmap())
338 elif evt.key() in [Qt.Key.Key_Enter, Qt.Key.Key_Return]: 362 elif evt.key() in [Qt.Key.Key_Enter, Qt.Key.Key_Return]:
339 self.__grabRegion() 363 self.__grabRegion()
340 else: 364 else:
341 evt.ignore() 365 evt.ignore()
342 366
343 def __grabRegion(self): 367 def __grabRegion(self):
344 """ 368 """
345 Private method to grab the selected region (i.e. do the snapshot). 369 Private method to grab the selected region (i.e. do the snapshot).
346 """ 370 """
347 pol = QPolygon(self.__selection) 371 pol = QPolygon(self.__selection)
348 if not pol.isEmpty(): 372 if not pol.isEmpty():
349 self.__grabbing = True 373 self.__grabbing = True
350 374
351 xOffset = self.__pixmap.rect().x() - pol.boundingRect().x() 375 xOffset = self.__pixmap.rect().x() - pol.boundingRect().x()
352 yOffset = self.__pixmap.rect().y() - pol.boundingRect().y() 376 yOffset = self.__pixmap.rect().y() - pol.boundingRect().y()
353 translatedPol = pol.translated(xOffset, yOffset) 377 translatedPol = pol.translated(xOffset, yOffset)
354 378
355 pixmap2 = QPixmap(pol.boundingRect().size()) 379 pixmap2 = QPixmap(pol.boundingRect().size())
356 pixmap2.fill(Qt.GlobalColor.transparent) 380 pixmap2.fill(Qt.GlobalColor.transparent)
357 381
358 pt = QPainter() 382 pt = QPainter()
359 pt.begin(pixmap2) 383 pt.begin(pixmap2)
360 if pt.paintEngine().hasFeature( 384 if pt.paintEngine().hasFeature(QPaintEngine.PaintEngineFeature.PorterDuff):
361 QPaintEngine.PaintEngineFeature.PorterDuff
362 ):
363 pt.setRenderHints( 385 pt.setRenderHints(
364 QPainter.RenderHint.Antialiasing | 386 QPainter.RenderHint.Antialiasing
365 QPainter.RenderHint.SmoothPixmapTransform, 387 | QPainter.RenderHint.SmoothPixmapTransform,
366 True) 388 True,
389 )
367 pt.setBrush(Qt.GlobalColor.black) 390 pt.setBrush(Qt.GlobalColor.black)
368 pt.setPen(QPen(QBrush(Qt.GlobalColor.black), 0.5)) 391 pt.setPen(QPen(QBrush(Qt.GlobalColor.black), 0.5))
369 pt.drawPolygon(translatedPol) 392 pt.drawPolygon(translatedPol)
370 pt.setCompositionMode( 393 pt.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
371 QPainter.CompositionMode.CompositionMode_SourceIn)
372 else: 394 else:
373 pt.setClipRegion(QRegion(translatedPol)) 395 pt.setClipRegion(QRegion(translatedPol))
374 pt.setCompositionMode( 396 pt.setCompositionMode(QPainter.CompositionMode.CompositionMode_Source)
375 QPainter.CompositionMode.CompositionMode_Source) 397
376
377 pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect()) 398 pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect())
378 pt.end() 399 pt.end()
379 400
380 self.grabbed.emit(pixmap2) 401 self.grabbed.emit(pixmap2)

eric ide

mercurial