Python自定义快捷屏幕截图
编辑:梨涡 分类:python 日期:2025-03-03 20:13:52 访问量:89

背景与功能
该程序为解决用户频繁手动截图、整理文件的低效问题而设计,尤其适合需要批量截取屏幕内容的工作场景(如竞品功能对比、视频关键帧存档)。用户通过预定义快捷键触发截图,程序自动捕获屏幕指定区域(如REGION坐标范围)或全屏画面,并按时间戳命名文件保存至指定目录(如D:\WorkFiles\...),全程无需操作文件管理器。

核心特性

  1. 快捷键驱动:支持自定义截图键(如小键盘0)和退出键(ESC),操作无缝衔接工作流程;
  2. 即时反馈:通过顶层Tkinter窗口显示截图结果提示(如“截图已保存:screen_20240510_113000.png”),提示框自动居中且1秒后消失,避免干扰用户操作;
  3. 线程安全设计:利用队列(Queue)传递GUI事件,分离键盘监听与界面渲染逻辑,防止界面卡顿;
  4. 灵活配置:开放区域坐标、保存路径、快捷键等参数,适配不同屏幕分辨率和项目需求。

技术实现
程序基于keyboard库实现全局热键监听,结合PIL.ImageGrab完成屏幕图像采集,利用Tkinterafter方法实现异步GUI更新。通过os模块自动创建多级保存目录,确保文件存储可靠性。代码结构清晰,预留扩展接口,可轻松集成OCR识别、图片压缩等进阶功能。

适用场景
适用于产品调研、远程协作、教育培训等需快速存档屏幕信息的场景,显著提升操作效率。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import keyboard
from PIL import ImageGrab
import tkinter as tk
import time
import os
from queue import Queue

# ============== 配置区域 ==============
REGION = (425, 65, 1490, 914)  # 截图坐标 (左x, 上y, 右x, 下y),微信截图、QQ截图取屏幕坐标,截全屏就等于None
# REGION = None   # 截全屏
SAVE_PATH = r"D:\WorkFiles\产品中心\0 竞品调研\视频截图"
# HOTKEY = "num 0"  # 截图快捷键,小键盘0
HOTKEY = "page down"  # 向下翻页键作为截图快捷键
EXIT_KEY = "esc"  # 退出程序键
TIP_DURATION = 1000  # 提示显示时间(毫秒)


# ========================================


class ScreenshotHelper:
    def __init__(self):
        self.counter = 1
        self.queue = Queue()
        self.init_directory()

        # 初始化Tkinter主线程
        self.root = tk.Tk()
        self.root.withdraw()

        # 启动主循环定时器
        self.root.after(100, self.process_gui_events)

        print("截图工具已就绪")
        print(f"快捷键:{HOTKEY.upper()} 截图")
        print(f"退出键:{EXIT_KEY.upper()}")

    def init_directory(self):
        """创建保存目录"""
        if not os.path.exists(SAVE_PATH):
            os.makedirs(SAVE_PATH)

    def show_notification(self, message):
        """通过队列发送通知到主线程"""
        self.queue.put(message)

    def process_gui_events(self):
        """主线程定时处理GUI事件"""
        try:
            while not self.queue.empty():
                message = self.queue.get_nowait()
                self._create_notification_window(message)
        finally:
            # 持续轮询队列
            self.root.after(100, self.process_gui_events)

    def _create_notification_window(self, message):
        """创建固定尺寸提示窗口"""
        tip = tk.Toplevel()
        tip.attributes("-topmost", True)
        tip.overrideredirect(True)

        # 配置提示信息窗口尺寸
        WINDOW_WIDTH = 300  # 可修改的宽度
        WINDOW_HEIGHT = 30  # 可修改的高度

        # 设置窗口不可调整大小
        tip.resizable(False, False)

        # 设置样式(背景色与标签一致)
        tip.configure(
            bg="#90EE90",
            padx=5,
            pady=2
        )

        # 创建标签(自动适应窗口尺寸)
        label = tk.Label(tip,
                         text=message,
                         fg="white",
                         bg="#90EE90",
                         font=("微软雅黑", 9),  # 根据高度调整字号
                         wraplength=WINDOW_WIDTH - 10)  # 自动换行宽度
        label.pack(fill=tk.BOTH, expand=True)  # 填充整个窗口

        # 固定窗口尺寸
        tip.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")

        # 定位窗口到屏幕顶部居中
        screen_width = self.root.winfo_screenwidth()
        # screen_height = self.root.winfo_screenheight()
        x = (screen_width - WINDOW_WIDTH) // 2
        y = 20  # 距屏幕顶部20像素,可根据需要调整
        tip.geometry(f"+{x}+{y}")

        # 自动销毁
        tip.after(TIP_DURATION, tip.destroy)

    def capture(self):
        """截图操作"""
        try:
            filename = f"screen_{time.strftime('%Y%m%d_%H%M%S')}.png"
            filepath = os.path.join(SAVE_PATH, filename)

            # 截图并保存
            img = ImageGrab.grab(bbox=REGION) if REGION else ImageGrab.grab()
            img.save(filepath)

            # 发送通知到GUI线程
            self.show_notification(f"截图已保存:{filename}")
            print(f"截图已保存:{os.path.join(SAVE_PATH, filename)}")
            self.counter += 1

        except Exception as e:
            self.show_notification(f"截图失败:{str(e)}")

    def exit_program(self):
        """安全退出程序"""
        self.root.quit()
        self.root.destroy()
        print("正在退出程序...")



if __name__ == '__main__':
    helper = ScreenshotHelper()
    keyboard.add_hotkey(HOTKEY, helper.capture)
    keyboard.add_hotkey(EXIT_KEY, helper.exit_program)


    # 启动主循环
    helper.root.mainloop()
    print("程序已安全退出")

 

返回顶部