Выделение экрана зажатием мыши как в lightshot на Python'е

Пытаюсь сделать программу, которая будет выделять экран зажатием клавиши ЛКМ в прямоугольник как в lightshot, в дальнейшем делать скриншот этой выделенной области.

Вот я сделал программу, которая делает скриншот выделенной области, но мне нужна визуализация выделения.

from PIL import ImageGrab
from pynput.mouse import Listener, Controller


def on_press(x, y, button, pressed):
    global first_x, first_y, second_x, second_y
    if pressed:
        print(F"Pressed at {x, y}")
        first_x, first_y = x, y
    else:
        second_x, second_y = x, y
        print(f"Released at {x, y}")

    if not pressed:
        # Stop listener
        return False

with Listener(on_click=on_press) as listener:
    listener.join()
minim_x = min(first_x, second_x)
maxim_x = max(first_x, second_x)

minim_y = min(first_y, second_y)
maxim_y = max(first_y, second_y)

im = (ImageGrab.grab(bbox=(minim_x, minim_y, maxim_x, maxim_y)))
im.show()

Ответы (1 шт):

Автор решения: S. Nick

Прежде чем запустить мой пример, убедитесь, что вы установили PyQt5

pip install PyQt5
pip install pyqt5-tools

PyQt — реализация фреймворка Qt для языка Python.

Да и создайте папку testpic рядом с main.py


main.py

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PIL import ImageGrab


class SnippingWidget(QtWidgets.QMainWindow):
    closed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(SnippingWidget, self).__init__(parent)
        self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
        self.setStyleSheet("background:transparent;")
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

        self.outsideSquareColor = "red"
        self.squareThickness = 2

        self.start_point = QtCore.QPoint()
        self.end_point = QtCore.QPoint()

    def mousePressEvent(self, event):
        self.start_point = event.pos()
        self.end_point = event.pos()
        self.update()

    def mouseMoveEvent(self, event):
        self.end_point = event.pos()
        self.update()

    def mouseReleaseEvent(self, QMouseEvent):
        r = QtCore.QRect(self.start_point, self.end_point).normalized()
        self.hide()
        img = ImageGrab.grab(bbox=r.getCoords())
#                 vvvvvvv <---- создайте папку, например testpic 
        img.save("testpic/testImage.png")
        QtWidgets.QApplication.restoreOverrideCursor()
        self.closed.emit()
        self.start_point = QtCore.QPoint()
        self.end_point = QtCore.QPoint()

    def paintEvent(self, event):
        trans = QtGui.QColor(22, 100, 233)
        r = QtCore.QRectF(self.start_point, self.end_point).normalized()
        qp = QtGui.QPainter(self)
        trans.setAlphaF(0.2)
        qp.setBrush(trans)
        outer = QtGui.QPainterPath()
        outer.addRect(QtCore.QRectF(self.rect()))
        inner = QtGui.QPainterPath()
        inner.addRect(r)
        r_path = outer - inner
        qp.drawPath(r_path)
        qp.setPen(
            QtGui.QPen(QtGui.QColor(self.outsideSquareColor), self.squareThickness)
        )
        trans.setAlphaF(0)
        qp.setBrush(trans)
        qp.drawRect(r)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralWidget = QtWidgets.QWidget()
        self.setCentralWidget(self.centralWidget)

        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.button = QtWidgets.QPushButton('Делать скриншот')
        self.button.clicked.connect(self.activateSnipping)
        
        layout = QtWidgets.QVBoxLayout(self.centralWidget)
        layout.addWidget(self.label, 1)
        layout.addWidget(self.button, 0)

        self.snipper = SnippingWidget()
        self.snipper.closed.connect(self.on_closed)

    def activateSnipping(self):
        self.snipper.showFullScreen()
        QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.CrossCursor)
        self.hide()

    def on_closed(self):
        pixmap = QtGui.QPixmap("testpic/testImage.png")
        self.label.setPixmap(pixmap)
        self.show()
        self.adjustSize()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.resize(400, 300)
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка