吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2381|回复: 5
收起左侧

[Python 原创] 方便快捷的桌面悬浮截图工具

[复制链接]
恋丶你的语 发表于 2023-9-25 15:31
本帖最后由 恋丶你的语 于 2023-9-25 15:41 编辑

最近正在学习Python,于是自己尝试着弄了一个:桌面悬浮截图工具。
亮点一:随时悬浮在桌面,方便对账
               这款截图工具具有独特的悬浮窗口设计,可以随时悬浮在您的桌面上。无论您是在浏览网页、编辑文档还是进行账目对账,只需轻轻点击,即可快速选择并截取所需区域。再也不用频繁切换窗口,工作更加高效!
亮点二:自定义截图区域,精确捕捉画面
               利用该工具,您可以自定义截图区域,精确捕捉所需的屏幕画面。通过简单的鼠标拖拽,即可快速框选所需区域,并即时展示截图的宽度和高度,让您轻松把握画面尺寸。
亮点三:丰富的功能,简单易用
该截图工具提供了多种功能,方便您在截图后进行进一步操作:
  • 保存截图:支持将截图保存为PNG格式的文件,并可自定义保存路径,方便后续查阅和使用。
  • 复制到剪贴板:一键将截图复制到剪贴板,随时粘贴到其他应用程序中,方便快捷。
  • 拖拽调整位置:截图后,您可以通过拖拽来调整截图窗口的位置,使其更符合您的工作需求。


不足一:还没有弄托盘图标
不足二:没有设置快捷方式截图
不足三:打包后程序体积很大,本来目标是状态10M以内,超过了所以不打包成品程序了。

47f9973239318f5d9fc0b15436d942b.png
494248d54208ed4d93fd62e72cf13de.png
[Python] 纯文本查看 复制代码
import tkinter as tk 
import io
from tkinter import Menu, messagebox, filedialog
from PIL import Image, ImageGrab, ImageTk
import pyperclip
import win32clipboard

class ScreenshotApp:    # 定义ScreenshotApp类
    def __init__(self):    # 初始化函数
        self.root = tk.Tk() 
        self.root.attributes('-alpha', 0.3)
        self.root.attributes('-fullscreen', True)
        self.root.iconbitmap("icon.ico")
        self.root.title("截图图")
        self.root.bind("<Escape>", lambda event: self.on_escape())    # 绑定Esc键触发on_escape()函数

        self.x1, self.y1, self.x2, self.y2 = 0, 0, 0, 0    # 初始化坐标变量
        self.rect = None    # 初始化矩形对象
        self.text = None    # 初始化文本对象

        self.canvas = tk.Canvas(self.root, cursor='cross')    # 创建画布对象
        self.canvas.pack(fill='both', expand=True)    # 将画布填充窗口并展开

        self.canvas.bind('<ButtonPress-1>', self.on_mouse_down)    # 绑定鼠标左键按下事件
        self.canvas.bind('<B1-Motion>', self.on_mouse_move)    # 绑定鼠标左键拖动事件
        self.canvas.bind('<ButtonRelease-1>', self.on_mouse_up)    # 绑定鼠标左键释放事件
        
    def on_escape(self):    # 当按下Esc键时触发的函数
        exit() 

    def run(self):    # 运行应用程序的函数
        self.root.mainloop() 

    def on_mouse_down(self, event):    # 当鼠标左键按下时触发的函数
        self.x1, self.y1 = event.x, event.y
        self.rect = self.canvas.create_rectangle(self.x1, self.y1, self.x1, self.y1, outline='red') 
        self.text = self.canvas.create_text(self.x1 + 5, self.y1 + 5, text='0x0', anchor='nw')

    def on_mouse_move(self, event):    # 当鼠标拖动时触发的函数
        self.x2, self.y2 = event.x, event.y
        self.canvas.coords(self.rect, self.x1, self.y1, self.x2, self.y2)
        width = abs(self.x2 - self.x1)    # 计算宽度
        height = abs(self.y2 - self.y1)    # 计算高度
        self.canvas.itemconfig(self.text, text=f'{width}x{height}')

    def on_mouse_up(self, event):    # 当鼠标左键释放时触发的函数
        self.x2, self.y2 = event.x, event.y
        self.canvas.coords(self.rect, self.x1, self.y1, self.x2, self.y2)
        self.capture_screenshot()
        self.root.quit()

    def capture_screenshot(self):    # 截图函数
        self.root.withdraw()

        left = min(self.x1, self.x2)
        top = min(self.y1, self.y2)
        right = max(self.x1, self.x2)
        bottom = max(self.y1, self.y2)

        image = ImageGrab.grab(bbox=(left, top, right, bottom))    # 截取屏幕上指定区域的图像
        self.create_new_window(image)    # 创建新窗口并显示截图

    def create_new_window(self, image):    # 创建新窗口并显示截图的函数
        new_window = tk.Toplevel(self.root)
        new_window.title("截图图")

        if self.x2 >= self.x1 and self.y2 >= self.y1:    # 如果从左上到右下拖动鼠标
            new_window.geometry(f"{image.width}x{image.height}+{self.x1}+{self.y1}")    # 设置窗口的宽度、高度和位置
        elif self.x2 >= self.x1 and self.y2 <= self.y1: 
            new_window.geometry(f"{image.width}x{image.height}+{self.x1}+{self.y2}") 
        elif self.x2 <= self.x1 and self.y2 <= self.y1: 
            new_window.geometry(f"{image.width}x{image.height}+{self.x2}+{self.y2}") 
        elif self.x2 <= self.x1 and self.y2 >= self.y1: 
            new_window.geometry(f"{image.width}x{image.height}+{self.x2}+{self.y1}") 

        image_tk = ImageTk.PhotoImage(image)    # 创建用于显示图片的PhotoImage对象
        label = tk.Label(new_window, image=image_tk)    # 创建标签对象并显示图片
        label.image = image_tk    # 保存图片对象的引用
        label.pack()    # 将标签添加到窗口中

        new_window.bind("<Button-1>", lambda event: self.start_drag(event, new_window))    # 绑定鼠标左键点击事件以触发拖拽
        label.bind('<B1-Motion>', lambda event: self.on_label_drag(event, new_window))    # 绑定标签的鼠标左键拖动事件

        new_window.overrideredirect(True) 
        new_window.wm_attributes('-topmost', True)    # 将窗口置于最顶层
        new_window.configure(borderwidth=1, relief='solid') 

        menu = Menu(new_window, tearoff=0)    # 创建菜单对象
        menu.add_command(label="保存", command=lambda: self.save_screenshot(image))    # 添加“保存”菜单项,并绑定保存截图函数
        menu.add_command(label="复制", command=lambda: self.copy_screenshot_to_clipboard(image))    # 添加“复制”菜单项,并绑定复制截图到剪贴板函数
        menu.add_separator()    # 添加分隔线
        #menu.add_command(label="取消", command=new_window.destroy)    # 添加“取消”菜单项,并绑定关闭窗口函数
        menu.add_command(label="取消", command=exit)    # 添加“取消”菜单项,并绑定退出程序函数
        label.bind('<Button-3>', lambda event: menu.post(event.x_root, event.y_root))    # 绑定标签的鼠标右键点击事件以显示菜单

        new_window.mainloop()    # 进入新窗口的主事件循环

    def save_screenshot(self, image):    # 保存截图函数
        filename = filedialog.asksaveasfilename(defaultextension=".png",
                                                filetypes=(("PNG files", "*.png"), ("All files", "*.*")))
        if filename:
            try:
                image.save(filename, "PNG") 
                messagebox.showinfo("保存成功", "截图已保存。")
            except Exception as e:
                messagebox.showerror("保存失败", f"保存截图时出现错误:{str(e)}") 

    def copy_screenshot_to_clipboard(self, image):    # 复制截图到剪贴板函数
        image = image.convert("RGB") 

        with io.BytesIO() as output:
            try:
                image.save(output, format="BMP") 
                data = output.getvalue()[14:]
                win32clipboard.OpenClipboard()
                win32clipboard.EmptyClipboard() 
                win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
                win32clipboard.CloseClipboard()
                messagebox.showinfo("复制成功", "截图已复制到剪贴板。") 
            except Exception as e:
                messagebox.showerror("复制失败", f"复制到剪贴板时出现错误:{str(e)}")

    def start_drag(self, event, new_window):    # 开始拖拽函数
        new_window.drag_data = {} 
        new_window.drag_data["x"] = event.x 
        new_window.drag_data["y"] = event.y 

    def on_label_drag(self, event, new_window):    # 标签拖拽函数
        dx = event.x - new_window.drag_data["x"]
        dy = event.y - new_window.drag_data["y"]
        new_x = new_window.winfo_x() + dx
        new_y = new_window.winfo_y() + dy
        new_window.geometry(f"+{new_x}+{new_y}")    # 根据位移更新窗口位置

if __name__ == "__main__":
    app = ScreenshotApp()    # 创建ScreenshotApp对象
    app.run()    # 运行截图应用程序

# 调用截图功能函数
app = ScreenshotApp()
app.run()


感觉逻辑有点乱,想了解有什么方法可以减少打包后体积。
打包的源码及图标:https://tars.lanzoue.com/iCpnV19v81of  密码:3bew

悬浮截图—截图图.zip

15.45 KB, 下载次数: 62, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 7吾爱币 +13 热心值 +5 收起 理由
junjia215 + 1 + 1 用心讨论,共获提升!
wushaominkk + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
aa20221101 + 1 + 1 热心回复!
yunce + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
sunny5888 + 1 谢谢@Thanks!
blindcat + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
一场荒唐半生梦 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

超级黄金多拉 发表于 2023-9-25 17:57
感谢楼主分享
blindcat 发表于 2023-9-25 18:15
REXLEE95 发表于 2023-9-25 18:23
pyinstaller打包,体积是挺大的,你可以试试创建一个干净的虚拟环境,只安装必须要的库,再进行打包。本地的库已经安装了许多第三方所以体积很大吧
头像被屏蔽
moruye 发表于 2023-9-25 21:43
提示: 作者被禁止或删除 内容自动屏蔽
烟筱禹 发表于 2023-9-29 23:02
感谢楼主无私分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表