You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Canvas 按鼠标位置删除图形功能异常问题求助

问题定位

  • 核心问题:Tkinter Canvas的标签(tags)仅支持字符串类型,你创建矩形时传入坐标元组作为tags参数,Tkinter会将元组的两个数值拆分为两个独立的字符串标签,而非将整个元组作为单个标签,因此删除时传入坐标元组找不到对应元素。
  • 坐标计算错误:你已经调用canvasx/canvasy方法对鼠标坐标做了画布偏移校正,但后续计算网格坐标xg/yg时仍然使用原始的e.x/e.y,如果画布存在滚动、平移偏移,计算出的网格坐标会和实际画布坐标不匹配。
  • 数据映射缺失:names字典仅存储了坐标值,没有建立坐标和对应矩形ID/标签的映射,也没有在删除后清除names中的无效数据,会导致后续判断残留脏数据。
  • 无效代码冗余:创建/删除分支里重复计算了多次相同变量,没有复用开头的计算结果。

修复方案

修复要点

  1. 把坐标元组转成唯一的字符串作为标签,保证能唯一匹配对应矩形
  2. 计算网格坐标时使用校正后的xx/yy,避免画布偏移导致的坐标偏差
  3. 调整names字典的存储逻辑,删除后同步清除names里的对应项
  4. 移除重复的冗余计算代码

修复后代码

names = {}
i = 0
a = 40
GRID = 40 # 可根据你的实际GRID取值调整

def evn(e):
    # 统一做坐标校正,后续所有计算都用xx/yy
    xx = c.canvasx(e.x)
    yy = c.canvasy(e.y)
    t = c.find_withtag('point')
    # 用校正后的坐标算网格位置
    xg = (xx + GRID/2) // GRID
    yg = (yy + GRID/2) // GRID
    grid_pos = (xg * GRID, yg * GRID)
    # 生成唯一字符串标签,适配Canvas的tags规则
    pos_tag = f"pos_{int(xg)}_{int(yg)}"
    
    if tool == 1:
        global i
        i += 1
        # 存储坐标和对应标签的映射
        names[i] = grid_pos
        oc = get_oval_centre(c.bbox(t))
        oc[0] += GRID
        oc[1] += GRID
        # 传入字符串作为tag
        rect_id = c.create_rectangle(-12, -12, 12, 12, fill='white', outline='white', tags=pos_tag)
        set_oval_coords(rect_id, grid_pos)
    elif tool == 5:
        oc = get_oval_centre(c.bbox(t))
        oc[0] += GRID
        oc[1] += GRID
        if grid_pos in names.values():
            print('found')
            # 用字符串标签删除对应元素
            c.delete(pos_tag)
            # 同步清除names里的无效数据
            for key in list(names.keys()):
                if names[key] == grid_pos:
                    del names[key]

补充说明

如果你的set_oval_coords方法是针对圆形元素实现的,建议替换为适配矩形的坐标设置方法,避免矩形位置出现非预期偏移。

内容的提问来源于stack exchange,提问作者MechaBrix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:24:02