Выделение экрана зажатием мыши как в 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_())
