【PyQt6] 框选截图功能

1 简介

书接上回, 全屏截图实现起来很简单, 来点稍微复杂点的, 框选截图
原理很简单, 弄个控件实现全屏半透视, 在全屏控件上画一个选框或者再弄一个几乎全透的子控件,实现鼠标拖动,缩放,移动, 键盘wasd 微调

用一个控件实现起来会很完美, 但是逻辑全部堆砌在一起,看代码会很累, 用一个子控件分开来写,逻辑清晰, 看着也舒服点,有机会以后在组合在一起,关键实现了一个独立的橡皮框控件, 想复用也容易.

Qt6 自身有个橡皮筋控件, 尝试了下, 可以当简单的框选工具, 比如选择多个item之类的,如果功能不需要复杂,倒是可以直接使用.

原本打算扩展这个控件[QRubberBand]的,想想又没必要, 干脆就直接扩展 QWidget

2 Demo 代码

2.1 Rubber 控件

框选控件, 双击鼠标左键 发出选中的区域
在这里插入图片描述

from PyQt6.QtCore import QEvent, Qt, QPoint, QPointF, QRectF, QRect, QTimer, pyqtSignal, QLineF
from PyQt6.QtGui import QEnterEvent, QMouseEvent, QPainter, QPaintEvent, QPen, QVector2D, QKeyEvent, QCursor, QColor
from PyQt6.QtWidgets import QWidget, QApplication


class Rubber(QWidget):
    confirm_selected = pyqtSignal(QRect)

    # ===============  构造函数 ==============================
    def __init__(self, parent=None) -> None:
        super().__init__(parent)
        self.hide()  # 默认隐藏

        # self.corners = [QRectF]   # 保存4个角的rect

        self.corner_i = -1  # 保存角的索引

        self.orgin = QPoint()   # 保存鼠标按下的坐标

        self.select_rect = QRectF()  # 保存调整后的区域,即实线区
        self.txt_height = 10        # 留出高度 显示字符串

        self.isLeftButton = False       # 鼠标是否为移动状态

    # ===============  绘制事件 ==============================
    def paintEvent(self, a0: QPaintEvent | None) -> None:
        """绘制事件
        """
        painter = QPainter(self)
        painter.setClipRect(a0.rect())

        # 填充背景
        painter.fillRect(self.rect(), QColor(255, 255, 255, 1))

        pen = QPen()
        color = Qt.GlobalColor.red
        pen.setColor(color)
        pen.setWidth(0)
        painter.setPen(pen)

        # 绘制 4 个角区域 以及 选区框
        self.drawCornors(painter)

        w = int(self.select_rect.width() * self.devicePixelRatio())
        h = int(self.select_rect.height() * self.devicePixelRatio())
        txt = f'{
     w}x{
     h}'
        painter.drawText(0, self.txt_height, txt)
    # ===============  鼠标进入事件 ==============================

    def enterEvent(self, event: QEnterEvent | None) -> None:
        self.setMouseTracking(True)
        self.setFocus()
        # self.__setCursorShape(Qt.CursorShape.SizeAllCursor)

    # ===============  鼠标离开事件 ==============================
    def leaveEvent(self, a0: QEvent | None) -> None:
        self.setMouseTracking(False)
        self.clearFocus()
        # return super().leaveEvent(a0)

    # ===============  鼠标按下事件 ==============================
    def mousePressEvent(self, a0: QMouseEvent | None) -> None:
        self.orgin = a0.pos()
        self.orgin1 = a0.pos()
        # print(self.orgin1 == self.orgin, id(self.orgin1), id(self.orgin))
        if a0.buttons() == Qt.MouseButton.LeftButton:
            self.isLeftButton = True

    # ===============  鼠标移动事件 ==============================
    def mouseMoveEvent(self, a0: QMouseEvent | None) -> None:
        pos_c 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值