PySimpleGUI问题:如何删除Canvas指定DrawImage而不删除背景图像
PySimpleGUI 画布点击删除指定上层元素保留背景的解决方案
问题根因
占满整个画布的背景图会被所有坐标点命中,get_figures_at_location()返回的元素列表默认包含背景图ID,直接删除返回的全部元素就会连带背景一起删除。
可行解决方案
- 第一步:初始化时单独存储背景图唯一ID
调用draw_image()加载背景图时,方法会返回该元素的唯一标识ID,将这个ID单独存储作为后续的排除项:# 示例:创建画布并加载背景,存储背景ID import PySimpleGUI as sg CANVAS_W = 800 CANVAS_H = 600 layout = [ [sg.Canvas(size=(CANVAS_W, CANVAS_H), key='-CANVAS-', enable_events=True)] ] window = sg.Window('画布点击删除示例', layout, finalize=True) canvas = window['-CANVAS-'] # 加载背景,存储返回的背景ID bg_fig_id = canvas.draw_image(filename='你的背景图路径.png', location=(0, CANVAS_H)) # 后续加载5个上层DrawImage元素 # 示例:img1_id = canvas.draw_image(...) - 第二步:点击事件中过滤背景ID再执行删除
捕获画布点击事件后,拿到坐标对应的所有元素ID列表,过滤掉预先存储的背景ID,取剩余列表的第一个元素(堆叠顺序最上层的元素即为你点击的目标元素),仅删除该元素即可:while True: event, values = window.read() if event == sg.WIN_CLOSED: break # 响应画布点击事件 if event == '-CANVAS-': click_x, click_y = values['-CANVAS-'] # 获取当前点击坐标下的所有元素ID fig_list = canvas.get_figures_at_location((click_x, click_y)) target_id = None # 遍历过滤背景ID,取第一个非背景元素 for fig_id in fig_list: if fig_id != bg_fig_id: target_id = fig_id break # 存在目标元素则删除 if target_id: canvas.delete_figure(target_id) window.close() - 可选优化:如果有多个固定保留的底层元素,可以把所有不需要删除的ID存入一个集合,过滤时判断元素ID是否在保留集合中即可适配更多场景。
内容的提问来源于stack exchange,提问作者GB DPA
相关产品推荐
相关产品推荐

