Python 截图 快捷键截图,一个基于PyQt5的截图,简易截图,自由截图 --pyqt5 入门

最近心血来潮,就想自己写一个截图的小工具,使用PyQt5实现一个简易的截图工具,按下快捷键就可以进行截图


需要安装的包:

pip install PyQt5
pip install keyboard

思路

  • 截取全屏的图片并保存下来
  • 把截取的图片显示出来,再加上一层阴影
  • 用鼠标选取需要截取的内容并保存下来
  • 选取的部分去掉阴影显示出来
  • 把图片变成图片文件存储起来

具体步骤

1、 初始化窗口,设置鼠标监听,设置十字光标,还有就是设置窗口无边框和窗口全屏。

def initWindow(self):
    self.setMouseTracking(True)     # 鼠标追踪
    self.setCursor(Qt.CrossCursor)  # 设置光标
    self.setWindowFlag(Qt.FramelessWindowHint)  # 窗口无边框
    self.setWindowState(Qt.WindowFullScreen)    # 窗口全屏

2、 获取全屏的图片。

def captureFullScreen(self):
    self.fullScreenImage = QGuiApplication.primaryScreen().grabWindow(QApplication.desktop().winId())

3、 填充步骤一获取到的全屏图片到窗口, 并重写paintEvent事件, 使用QPainter来绘制全屏的图片到窗口。

def paintBackgroundImage(self):
    shadowColor = QColor(0, 0, 0, 100)  # 黑色半透明
    self.painter.drawPixmap(0, 0, self.fullScreenImage)
    self.painter.fillRect(self.fullScreenImage.rect(), shadowColor)     # 填充矩形阴影

def paintEvent(self, event):
    self.painter.begin(self)    # 开始重绘
    self.paintBackgroundImage()
    penColor = QColor(30, 144, 245)     # 画笔颜色
    self.painter.setPen(QPen(penColor, 1, Qt.SolidLine, Qt.RoundCap))    # 设置画笔,蓝色,1px大小,实线,圆形笔帽
    if self.isMousePressLeft is True:
        pickRect = self.getRectangle(self.beginPosition, self.endPosition)   # 获得要截图的矩形框
        self.captureImage = self.fullScreenImage.copy(pickRect)         # 捕获截图矩形框内的图片
        self.painter.drawPixmap(pickRect.topLeft(), self.captureImage)  # 填充截图的图片
        self.painter.drawRect(pickRect)     # 画矩形边框
    self.painter.end()  # 结束重绘

4、 完善步骤三中使用到的getRectangle()函数,意思时鼠标选取需要截取的区域, 利用paintEvent在窗口上显示出来。

def getRectangle(self, beginPoint, endPoint):
    pickRectWidth = int(qAbs(beginPoint.x() - endPoint.x()))
    pickRectHeight = int(qAbs(beginPoint.y() - endPoint.y()))
    pickRectTop = beginPoint.x() if beginPoint.x() < endPoint.x() else endPoint.x()
    pickRectLeft = beginPoint.y() if beginPoint.y() < endPoint.y() else endPoint.y()
    pickRect = QRect(pickRectTop, pickRectLeft, pickRectWidth, pickRectHeight)
    # 避免高度宽度为0时候报错
    if pickRectWidth == 0:
        pickRect.setWidth(2)
    if pickRectHeight == 0:
        pickRect.setHeight(2)

    return pickRect

5、 重写鼠标和键盘事件,鼠标左键点击开始记录坐标,鼠标左键释放记录结束的坐标,传递给paintEvent中的getRectangle(),开始坐标和结束坐标形成的矩形就是我们需要截图的区域,鼠标双击或者按Enter都可以保存图片,如果开始截图了,没有选取,按一次右键直接退出截图(或者按ESC也可以),如果选取了要截图的区域,按一次右键重新开始截图,类似于QQ截图。

def mousePressEvent(self, event):
    if event.button() == Qt.LeftButton:
        self.beginPosition = event.pos()	# 记录选取区域开始的坐标
        self.isMousePressLeft = True
    if event.button() == Qt.RightButton:
        # 如果选取了图片,则按一次右键开始重新截图
        if self.captureImage is not None:
            self.captureImage = None
            self.paintBackgroundImage()
            self.update()		# update的作用是调用paintEvent
        else:
            self.close()		# 关闭窗口

def mouseMoveEvent(self, event):
    if self.isMousePressLeft is True:
        self.endPosition = event.pos()	# 选取区域结束坐标
        self.update()

def mouseReleaseEvent(self, event):
    self.endPosition = event.pos()		#记录选取区域结束的坐标
    self.isMousePressLeft = False

def mouseDoubleClickEvent(self, event):
    if self.captureImage is not None:
        self.saveImage()		# 保存截图图片
        self.close()		# 关闭窗口

def keyPressEvent(self, event):
    if event.key() == Qt.Key_Escape:
        self.close()		# 关闭窗口
    if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
        if self.captureImage is not None:
            self.saveImage()	# 保存截图图片
            self.close()	# 关闭窗口

6、 保存图片

    def saveImage(self):
        self.captureImage.save('picture.png')   # 保存图片到当前文件夹中


以下是全部代码

import sys
import keyboard
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import Qt, qAbs, QRect
from PyQt5.QtGui import QPen, QPainter, QColor, QGuiApplication

class CaptureScreen(QWidget):
    # 初始化变量
    beginPosition = None
    endPosition = None
    fullScreenImage = None
    captureImage = None
    isMousePressLeft = None
    painter = QPainter()

    def __init__(self):
        super(QWidget, self).__init__()
        self.initWindow()   # 初始化窗口
        self.captureFullScreen()    # 获取全屏

    def initWindow(self):
        self.setMouseTracking(True)     # 鼠标追踪
        self.setCursor(Qt.CrossCursor)  # 设置光标
        self.setWindowFlag(Qt.FramelessWindowHint)  # 窗口无边框
        self.setWindowState(Qt.WindowFullScreen)    # 窗口全屏

    def captureFullScreen(self):
        self.fullScreenImage = QGuiApplication.primaryScreen().grabWindow(QApplication.desktop().winId())

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.beginPosition = event.pos()
            self.isMousePressLeft = True
        if event.button() == Qt.RightButton:
            # 如果选取了图片,则按一次右键开始重新截图
            if self.captureImage is not None:
                self.captureImage = None
                self.paintBackgroundImage()
                self.update()
            else:
                self.close()

    def mouseMoveEvent(self, event):
        if self.isMousePressLeft is True:
            self.endPosition = event.pos()
            self.update()

    def mouseReleaseEvent(self, event):
        self.endPosition = event.pos()
        self.isMousePressLeft = False

    def mouseDoubleClickEvent(self, event):
        if self.captureImage is not None:
            self.saveImage()
            self.close()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.close()
        if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
            if self.captureImage is not None:
                self.saveImage()
                self.close()

    def paintBackgroundImage(self):
        shadowColor = QColor(0, 0, 0, 100)  # 黑色半透明
        self.painter.drawPixmap(0, 0, self.fullScreenImage)
        self.painter.fillRect(self.fullScreenImage.rect(), shadowColor)     # 填充矩形阴影

    def paintEvent(self, event):
        self.painter.begin(self)    # 开始重绘
        self.paintBackgroundImage()
        penColor = QColor(30, 144, 245)     # 画笔颜色
        self.painter.setPen(QPen(penColor, 1, Qt.SolidLine, Qt.RoundCap))    # 设置画笔,蓝色,1px大小,实线,圆形笔帽
        if self.isMousePressLeft is True:
            pickRect = self.getRectangle(self.beginPosition, self.endPosition)   # 获得要截图的矩形框
            self.captureImage = self.fullScreenImage.copy(pickRect)         # 捕获截图矩形框内的图片
            self.painter.drawPixmap(pickRect.topLeft(), self.captureImage)  # 填充截图的图片
            self.painter.drawRect(pickRect)     # 画矩形边框
        self.painter.end()  # 结束重绘

    def getRectangle(self, beginPoint, endPoint):
        pickRectWidth = int(qAbs(beginPoint.x() - endPoint.x()))
        pickRectHeight = int(qAbs(beginPoint.y() - endPoint.y()))
        pickRectTop = beginPoint.x() if beginPoint.x() < endPoint.x() else endPoint.x()
        pickRectLeft = beginPoint.y() if beginPoint.y() < endPoint.y() else endPoint.y()
        pickRect = QRect(pickRectTop, pickRectLeft, pickRectWidth, pickRectHeight)
        # 避免高度宽度为0时候报错
        if pickRectWidth == 0:
            pickRect.setWidth(2)
        if pickRectHeight == 0:
            pickRect.setHeight(2)

        return pickRect

    def saveImage(self):
        self.captureImage.save('picture.png', quality=95)   # 保存图片到当前文件夹中

if __name__ == "__main__":
    keyboard.wait(hotkey='f4')  # 按F4开始截图
    app = QApplication(sys.argv)
    windows = CaptureScreen()
    windows.show()
    sys.exit(app.exec_())



因为我也是最近才开始学习PyQt5的,对于pyqt还是有挺多不懂的地方,如果有不懂的可以留言,或者有什么需要改进的也可以提出来

你可能感兴趣的:(Python,pyqt5)