方便快捷的桌面悬浮截图工具
本帖最后由 恋丶你的语 于 2023-9-25 15:41 编辑最近正在学习Python,于是自己尝试着弄了一个:桌面悬浮截图工具。
亮点一:随时悬浮在桌面,方便对账
这款截图工具具有独特的悬浮窗口设计,可以随时悬浮在您的桌面上。无论您是在浏览网页、编辑文档还是进行账目对账,只需轻轻点击,即可快速选择并截取所需区域。再也不用频繁切换窗口,工作更加高效!
亮点二:自定义截图区域,精确捕捉画面
利用该工具,您可以自定义截图区域,精确捕捉所需的屏幕画面。通过简单的鼠标拖拽,即可快速框选所需区域,并即时展示截图的宽度和高度,让您轻松把握画面尺寸。
亮点三:丰富的功能,简单易用
该截图工具提供了多种功能,方便您在截图后进行进一步操作:
[*]保存截图:支持将截图保存为PNG格式的文件,并可自定义保存路径,方便后续查阅和使用。
[*]复制到剪贴板:一键将截图复制到剪贴板,随时粘贴到其他应用程序中,方便快捷。
[*]拖拽调整位置:截图后,您可以通过拖拽来调整截图窗口的位置,使其更符合您的工作需求。
不足一:还没有弄托盘图标
不足二:没有设置快捷方式截图
不足三:打包后程序体积很大,本来目标是状态10M以内,超过了所以不打包成品程序了。
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()
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
感谢楼主分享 支持下楼主原创 pyinstaller打包,体积是挺大的,你可以试试创建一个干净的虚拟环境,只安装必须要的库,再进行打包。本地的库已经安装了许多第三方所以体积很大吧 感谢楼主无私分享
页:
[1]