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) |