如何在PySimpleGui界面中实现鼠标框选图片区域并保存坐标
基于PySimpleGUI实现图片区域框选方案
核心实现思路
- 复用PySimpleGUI底层Tkinter能力:PySimpleGUI的
sg.Image控件本质封装了Tkinter的Canvas组件,我们可以直接获取该底层对象绑定鼠标事件,不需要重构现有界面 - 事件绑定逻辑:绑定三个核心鼠标事件完成框选流程:
- 左键按下事件:记录框选起始点坐标
- 左键拖拽事件:实时绘制半透明选框,更新临时选框位置避免拖影
- 左键松开事件:记录框选结束点坐标,计算得到最终选中区域的左上角、右下角坐标
- 坐标适配:如果界面中的图片存在缩放显示,需要计算控件坐标到原始图片坐标的映射比例,保证保存的坐标对应原图真实位置
可运行示例代码
import PySimpleGUI as sg from PIL import Image, ImageTk # 全局变量存储框选坐标 start_x, start_y = 0, 0 end_x, end_y = 0, 0 current_rect = None # 若图片有缩放,设置缩放比例:scale = 原图尺寸 / 控件显示尺寸,例如原图1000x1000、控件显示500x500时scale=2 scale = 1 def on_mouse_down(event): global start_x, start_y, current_rect start_x, start_y = event.x, event.y # 清空之前的选框 if current_rect: img_canvas.delete(current_rect) def on_mouse_drag(event): global current_rect # 删除上一次绘制的临时选框 if current_rect: img_canvas.delete(current_rect) # 绘制新的选框,红色虚线边框,可自行调整样式 current_rect = img_canvas.create_rectangle(start_x, start_y, event.x, event.y, outline='red', dash=(2, 2)) def on_mouse_up(event): global end_x, end_y end_x, end_y = event.x, event.y # 转换为原图坐标 real_x1 = int(start_x * scale) real_y1 = int(start_y * scale) real_x2 = int(end_x * scale) real_y2 = int(end_y * scale) # 统一坐标格式,保证左上角坐标小于右下角 x1, x2 = min(real_x1, real_x2), max(real_x1, real_x2) y1, y2 = min(real_y1, real_y2), max(real_y1, real_y2) print(f"选中区域坐标:左上角({x1},{y1}),右下角({x2},{y2}),宽{x2-x1},高{y2-y1}") # 此处可自行添加坐标保存逻辑,存储到变量或文件中 # 加载示例图片,替换为你自己的图片路径 image_path = "test.png" pil_img = Image.open(image_path) img_width, img_height = pil_img.size tk_img = ImageTk.PhotoImage(pil_img) # 界面布局,图片放在sg.Frame中,和你现有界面结构保持一致 layout = [ [sg.Frame("图片框选区域", [ [sg.Image(key="-IMAGE-", data=tk_img)] ])], [sg.Button("退出")] ] window = sg.Window("图片框选示例", layout, finalize=True) # 获取Image控件对应的底层Tkinter Canvas对象 img_widget = window["-IMAGE-"].Widget img_canvas = img_widget # 绑定鼠标事件 img_canvas.bind("<ButtonPress-1>", on_mouse_down) img_canvas.bind("<B1-Motion>", on_mouse_drag) img_canvas.bind("<ButtonRelease-1>", on_mouse_up) # 事件循环 while True: event, values = window.read() if event in (sg.WIN_CLOSED, "退出"): break window.close()
注意事项
- 上述逻辑可以无缝嵌入你已经开发完成的PySimpleGUI界面,只需要把示例中
sg.Image的key替换为你现有代码中对应图片控件的key即可 - 选框样式可以自行修改
create_rectangle的参数,调整边框颜色、填充色、线型等属性 - 如果图片显示时做了缩放,必须提前计算
scale变量的值,否则保存的坐标和原图位置不匹配
内容的提问来源于stack exchange,提问作者Александр Трифонов
相关产品推荐
相关产品推荐

