it编程 > 前端脚本 > Python

Python结合PyQt6实现屏幕截图工具(附源码)

2人参与 2026-08-07 Python

一、源码分享

1、源码分享

import sys
import os
from pyqt6.qtwidgets import (qapplication, qmainwindow, qpushbutton, qwidget,
                             qvboxlayout, qlabel, qmessagebox, qdialog)
from pyqt6.qtgui import qscreen, qpixmap, qpainter, qcolor, qpen
from pyqt6.qtcore import qt, qrect, qpoint, qdatetime


class screenshotmask(qdialog):
    def __init__(self, full_screen_pix):
        super().__init__()
        self.full_pix = full_screen_pix
        # 全屏无边框置顶
        self.setwindowflags(
            qt.windowtype.framelesswindowhint
            | qt.windowtype.windowstaysontophint
        )
        self.setgeometry(0, 0, self.full_pix.width(), self.full_pix.height())
        self.setattribute(qt.widgetattribute.wa_translucentbackground)
        self.setmousetracking(true)

        self.start_pos = qpoint()
        self.end_pos = qpoint()
        self.is_drawing = false
        self.select_rect = qrect()
        self.result_pix = none

    def paintevent(self, event):
        painter = qpainter(self)
        # 底层原图
        painter.drawpixmap(self.rect(), self.full_pix)
        # 半透明遮罩
        painter.fillrect(self.rect(), qcolor(0, 0, 0, 130))

        if self.is_drawing:
            rect = qrect(self.start_pos, self.end_pos).normalized()
            # 选区清空遮罩
            painter.setcompositionmode(qpainter.compositionmode.compositionmode_clear)
            painter.fillrect(rect, qt.globalcolor.transparent)
            painter.setcompositionmode(qpainter.compositionmode.compositionmode_sourceover)
            # 绘制边框
            pen = qpen(qcolor(0, 160, 255), 2)
            painter.setpen(pen)
            painter.drawrect(rect)
            self.select_rect = rect

    def mousepressevent(self, event):
        if event.button() == qt.mousebutton.leftbutton:
            self.is_drawing = true
            self.start_pos = event.pos()
            self.end_pos = event.pos()
            self.update()

    def mousemoveevent(self, event):
        if self.is_drawing:
            self.end_pos = event.pos()
            self.update()

    def mousereleaseevent(self, event):
        if event.button() == qt.mousebutton.leftbutton and self.is_drawing:
            self.is_drawing = false
            if not self.select_rect.isempty():
                self.result_pix = self.full_pix.copy(self.select_rect)
            self.accept()  # 关闭对话框

    def keypressevent(self, event):
        if event.key() == qt.key.key_escape:
            self.reject()  # 取消截图


class mainwindow(qmainwindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setwindowtitle("pyqt6 截图工具")
        self.resize(300, 150)
        center = qwidget()
        self.setcentralwidget(center)
        layout = qvboxlayout(center)
        layout.setspacing(12)
        layout.setcontentsmargins(30, 30, 30, 30)

        btn_full = qpushbutton("全屏截图")
        btn_area = qpushbutton("区域拖拽截图")
        tip = qlabel("按住鼠标拖拽选区 | esc取消")
        tip.setalignment(qt.alignmentflag.aligncenter)
        tip.setstylesheet("color:#666")

        layout.addwidget(btn_full)
        layout.addwidget(btn_area)
        layout.addwidget(tip)

        btn_full.clicked.connect(self.capture_full)
        btn_area.clicked.connect(self.start_area_capture)

    def capture_full(self):
        screen = qapplication.primaryscreen()
        full_img = screen.grabwindow(0)
        time_str = qdatetime.currentdatetime().tostring("yyyymmdd_hhmmss")
        save_path = f"full_{time_str}.png"
        full_img.save(save_path, "png")
        qmessagebox.information(self, "保存成功", f"路径:\n{os.path.abspath(save_path)}")

    def start_area_capture(self):
        # 先隐藏主窗口,避免截图包含自身
        self.hide()
        qapplication.processevents()

        screen = qapplication.primaryscreen()
        full_img = screen.grabwindow(0)

        mask = screenshotmask(full_img)
        # 正确使用qdialog的exec(),不会卡死
        ret = mask.exec()

        # 截图完成后恢复窗口
        self.show()

        if ret == 1 and mask.result_pix is not none:
            time_str = qdatetime.currentdatetime().tostring("yyyymmdd_hhmmss")
            save_path = f"region_{time_str}.png"
            mask.result_pix.save(save_path, "png")
            qmessagebox.information(self, "区域截图完成", f"已保存:\n{os.path.abspath(save_path)}")


if __name__ == "__main__":
    app = qapplication(sys.argv)
    win = mainwindow()
    win.show()
    sys.exit(app.exec())

2、效果展示

二、详解

1、核心代码解析

导入模块

import sys
from pyqt6.qtwidgets import qapplication, qmainwindow, qpushbutton, qwidget, qvboxlayout
from pyqt6.qtgui import qscreen
from pyqt6.qtcore import qt

screenshotwindow类结构

class screenshotwindow(qmainwindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

界面初始化

def init_ui(self):
    self.setwindowtitle("屏幕截图工具")
    self.resize(300, 120)
    
    # 中心部件与布局
    central_widget = qwidget()
    self.setcentralwidget(central_widget)
    layout = qvboxlayout(central_widget)
    layout.setcontentsmargins(50, 30, 50, 30)
    
    # 截图按钮
    self.btn_capture = qpushbutton("点击截取全屏并保存png")
    self.btn_capture.clicked.connect(self.capture_screen)
    layout.addwidget(self.btn_capture, alignment=qt.alignmentflag.aligncenter)

2、截图功能详解

capture_screen方法

def capture_screen(self):
    # 获取主屏幕对象
    screen: qscreen = qapplication.primaryscreen()
    # 截取整个屏幕
    pixmap = screen.grabwindow(0)
    # 保存为png文件,保存在程序同级目录
    save_path = "screenshot.png"
    pixmap.save(save_path, "png")
    print(f"截图已保存至: {save_path}")

qapplication.primaryscreen()

screen.grabwindow(0)

pixmap.save()

3、关键api说明

qscreen类的重要方法

方法说明返回值
grabwindow(wid window, x=0, y=0, width=-1, height=-1)截取指定窗口区域qpixmap
geometry()获取屏幕的几何信息(位置和大小)qrect
availablegeometry()获取可用区域(排除任务栏等)qrect
name()获取屏幕名称str
devicepixelratio()获取设备像素比float

qpixmap类的重要方法

方法说明
save(filename, format)保存图像到文件
toimage()转换为qimage对象
scaled(width, height)缩放图像
copy(rect)复制指定区域

4、功能扩展建议

多显示器支持

def capture_all_screens(self):
    """截取所有屏幕"""
    screens = qapplication.screens()
    for i, screen in enumerate(screens):
        pixmap = screen.grabwindow(0)
        pixmap.save(f"screenshot_screen_{i}.png", "png")

选择保存路径

from pyqt6.qtwidgets import qfiledialog

def capture_with_dialog(self):
    screen = qapplication.primaryscreen()
    pixmap = screen.grabwindow(0)
    
    # 弹出文件保存对话框
    file_path, _ = qfiledialog.getsavefilename(
        self, 
        "保存截图", 
        "screenshot.png", 
        "png files (*.png);;jpeg files (*.jpg);;all files (*)"
    )
    
    if file_path:
        pixmap.save(file_path, "png")
        print(f"截图已保存至: {file_path}")

截取指定区域

def capture_region(self, x, y, width, height):
    """截取屏幕指定区域"""
    screen = qapplication.primaryscreen()
    pixmap = screen.grabwindow(0, x, y, width, height)
    return pixmap

添加时间戳

from datetime import datetime

def capture_with_timestamp(self):
    screen = qapplication.primaryscreen()
    pixmap = screen.grabwindow(0)
    
    # 生成带时间戳的文件名
    timestamp = datetime.now().strftime("%y%m%d_%h%m%s")
    save_path = f"screenshot_{timestamp}.png"
    
    pixmap.save(save_path, "png")
    print(f"截图已保存至: {save_path}")

5、常见问题与解决方案

权限问题

多显示器坐标系统

高dpi屏幕适配

# 启用高dpi支持
if hasattr(qt, 'aa_enablehighdpiscaling'):
    qapplication.setattribute(qt.aa_enablehighdpiscaling, true)
if hasattr(qt, 'aa_usehighdpipixmaps'):
    qapplication.setattribute(qt.aa_usehighdpipixmaps, true)

6、总结

本文详细介绍了使用pyqt6实现屏幕截图的核心技术:

  1. 基础实现: 使用qscreen.grabwindow()方法截取全屏
  2. 界面设计: 使用qmainwindowqvboxlayout创建简洁界面
  3. 文件保存: 使用qpixmap.save()方法保存为png格式
  4. 扩展功能: 提供了多显示器、区域截图、自定义保存路径等扩展方案

pyqt6的屏幕截图功能简单高效,适合需要集成截图功能的桌面应用程序开发。通过本文的示例代码和详细解析,读者可以快速掌握这一实用技术。

以上就是python结合pyqt6实现屏幕截图工具(附源码)的详细内容,更多关于pyqt屏幕截图的资料请关注代码网其它相关文章!

(0)

您想发表意见!!点此发布评论

推荐阅读

Python基础入门之模块搜索路径sys.path用法详解

08-07

一文详解Python文件操作与路径处理

08-07

Python+PyQt6实现将PDF文件转高清图片

08-07

Python中定时任务APScheduler框架使用教程

08-07

Python+PyQt6实现跨平台串口设备热插拔检测

08-07

Python difflib库实现文本差异比较与合并实战指南

08-07

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论