Mon, 07 Nov 2022 17:19:58 +0100
Corrected/acknowledged some bad import style and removed some obsolete code.
# -*- coding: utf-8 -*- # Copyright (c) 2019 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing a grabber object for non-Wayland desktops. """ from PyQt6.QtCore import QEvent, QObject, Qt, QTimer, pyqtSignal from PyQt6.QtGui import QCursor, QGuiApplication, QPixmap from PyQt6.QtWidgets import QWidget from eric7 import Globals from .SnapshotModes import SnapshotModes from .SnapshotTimer import SnapshotTimer class SnapshotDefaultGrabber(QObject): """ Class implementing a grabber object for non-Wayland desktops. @signal grabbed(QPixmap) emitted after the grab operation is finished """ grabbed = pyqtSignal(QPixmap) def __init__(self, parent=None): """ Constructor @param parent reference to the parent object @type QObject """ super().__init__(parent) self.__grabber = None self.__grabberWidget = QWidget(None, Qt.WindowType.X11BypassWindowManagerHint) self.__grabberWidget.move(-10000, -10000) self.__grabberWidget.installEventFilter(self) self.__grabTimer = SnapshotTimer() self.__grabTimer.timeout.connect(self.__grabTimerTimeout) def supportedModes(self): """ Public method to get the supported screenshot modes. @return tuple of supported screenshot modes @rtype tuple of SnapshotModes """ return ( SnapshotModes.FULLSCREEN, SnapshotModes.SELECTEDSCREEN, SnapshotModes.RECTANGLE, SnapshotModes.FREEHAND, SnapshotModes.ELLIPSE, ) def grab(self, mode, delay=0, captureCursor=False, captureDecorations=False): """ Public method to perform a grab operation potentially after a delay. @param mode screenshot mode @type ScreenshotModes @param delay delay in seconds @type int @param captureCursor flag indicating to include the mouse cursor (not used) @type bool @param captureDecorations flag indicating to include the window decorations (not used) @type bool """ self.__mode = mode if delay: self.__grabTimer.start(delay) else: QTimer.singleShot(200, self.__startUndelayedGrab) def __grabTimerTimeout(self): """ Private slot to perform a delayed grab operation. """ if self.__mode == SnapshotModes.RECTANGLE: self.__grabRectangle() elif self.__mode == SnapshotModes.ELLIPSE: self.__grabEllipse() elif self.__mode == SnapshotModes.FREEHAND: self.__grabFreehand() else: self.__performGrab(self.__mode) def __startUndelayedGrab(self): """ Private slot to perform an undelayed grab operation. """ if self.__mode == SnapshotModes.RECTANGLE: self.__grabRectangle() elif self.__mode == SnapshotModes.ELLIPSE: self.__grabEllipse() elif self.__mode == SnapshotModes.FREEHAND: self.__grabFreehand() else: if Globals.isMacPlatform(): self.__performGrab(self.__mode) else: self.__grabberWidget.show() self.__grabberWidget.grabMouse(Qt.CursorShape.CrossCursor) def __grabRectangle(self): """ Private method to grab a rectangular screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber(mode=SnapshotRegionGrabber.Rectangle) self.__grabber.grabbed.connect(self.__captured) def __grabEllipse(self): """ Private method to grab an elliptical screen region. """ from .SnapshotRegionGrabber import SnapshotRegionGrabber self.__grabber = SnapshotRegionGrabber(mode=SnapshotRegionGrabber.Ellipse) self.__grabber.grabbed.connect(self.__captured) def __grabFreehand(self): """ Private method to grab a non-rectangular screen region. """ from .SnapshotFreehandGrabber import SnapshotFreehandGrabber self.__grabber = SnapshotFreehandGrabber() self.__grabber.grabbed.connect(self.__captured) def __performGrab(self, mode): """ Private method to perform a screen grab other than a selected region. @param mode screenshot mode @type SnapshotModes """ self.__grabberWidget.releaseMouse() self.__grabberWidget.hide() self.__grabTimer.stop() if mode == SnapshotModes.FULLSCREEN: screen = QGuiApplication.screens()[0] vgeom = screen.availableVirtualGeometry() snapshot = screen.grabWindow( 0, vgeom.x(), vgeom.y(), vgeom.width(), vgeom.height() ) elif mode == SnapshotModes.SELECTEDSCREEN: screen = QGuiApplication.screenAt(QCursor.pos()) sgeom = screen.geometry() if Globals.isMacPlatform(): # macOS variant snapshot = screen.grabWindow( 0, sgeom.x(), sgeom.y(), sgeom.width(), sgeom.height() ) else: # Linux variant # Windows variant snapshot = screen.grabWindow(0, 0, 0, sgeom.width(), sgeom.height()) else: snapshot = QPixmap() self.grabbed.emit(snapshot) def __captured(self, pixmap): """ Private slot to show a preview of the snapshot. @param pixmap pixmap of the snapshot (QPixmap) """ self.__grabber.close() snapshot = QPixmap(pixmap) self.__grabber.grabbed.disconnect(self.__captured) self.__grabber = None self.grabbed.emit(snapshot) def eventFilter(self, obj, evt): """ Public method to handle event for other objects. @param obj reference to the object (QObject) @param evt reference to the event (QEvent) @return flag indicating that the event should be filtered out (boolean) """ if obj == self.__grabberWidget and evt.type() == QEvent.Type.MouseButtonPress: if QWidget.mouseGrabber() != self.__grabberWidget: return False if evt.button() == Qt.MouseButton.LeftButton: self.__performGrab(self.__mode) return False