Tkinter中如何检测鼠标是否在多边形对象上并响应点击?
解决Tkinter Canvas多边形点击事件的问题
你之前尝试的väiksemk.tk.active==True写法无效,核心原因是create_polygon返回的是画布元素的整数ID,不是带属性的对象,没法通过这种方式判断点击状态。下面提供两种可行的解决方案:
方法1:在全局点击事件中检测点击目标
利用Canvas的find_overlapping方法,在全局点击事件里判断当前点击位置是否命中目标多边形。修改你的hiir函数:
def hiir(event): global klõps, laius if klõps==0: # 处理开始按钮点击 if 250 < event.x < 450 and 325 < event.y < 375: tahvel.delete("all") klõps=1 ruudustik() # 处理多边形点击(减小宽度) elif tahvel.find_overlapping(event.x, event.y, event.x, event.y) == (väiksemk,): if laius > 1: # 防止宽度小于1 laius -= 1 print(f"当前宽度: {laius}") elif klõps==1: värvi(event.x, event.y)
find_overlapping(x1,y1,x2,y2)会返回覆盖该区域的所有画布元素ID,点击点的区域是(event.x,event.y)到自身,返回元组等于(väiksemk,)即说明命中目标多边形。
方法2:给多边形单独绑定点击事件
直接给目标多边形绑定<Button-1>事件,逻辑更清晰,无需依赖全局判断:
在创建多边形后添加绑定代码:
väiksemk=tahvel.create_polygon(250,470,270,480,270,460,fill="black",activefill="white") # 多边形点击事件处理函数 def väiksemk_klõps(event): global laius if laius > 1: laius -= 1 print(f"宽度已减小到: {laius}") # 绑定事件到多边形 tahvel.tag_bind(väiksemk, "<Button-1>", väiksemk_klõps)
tag_bind可以针对指定ID的画布元素绑定事件,点击该多边形时会直接触发对应的处理函数。
完整修改示例代码
以下是整合了两种方案(添加了增大宽度的多边形)的完整代码,同时优化了棋盘绘制逻辑:
from tkinter import* raam = Tk() tahvel = Canvas(raam, width=700, height=700, background="wheat") tahvel.grid() raam.resizable(0,0) # 初始化界面元素 tahvel.create_rectangle(450,375,250,325,fill="green") tahvel.create_text(350,350,text="alusta",fill="black") tahvel.create_text(175,470,text="mängulaua laius", fill="black",font=(30)) tahvel.create_text(175,490,text="mängulaua kõrgus", fill="black",font=(30)) # 创建调整宽度的多边形 väiksemk=tahvel.create_polygon(250,470,270,480,270,460,fill="black",activefill="white") suuremk=tahvel.create_polygon(300,470,280,480,280,460,fill="black",activefill="white") # 全局变量 klõps=0 värv=[[0 for _ in range(25)]for _ in range(25)] värv2=[[0 for _ in range(25)]for _ in range(25)] laius=25 kõrgus=25 # 多边形点击事件处理 def väiksemk_klõps(event): global laius if laius > 1: laius -= 1 print(f"当前宽度: {laius}") def suuremk_klõps(event): global laius if laius < 25: laius += 1 print(f"当前宽度: {laius}") tahvel.tag_bind(väiksemk, "<Button-1>", väiksemk_klõps) tahvel.tag_bind(suuremk, "<Button-1>", suuremk_klõps) def hiir(event): global klõps if klõps==0: if 250 < event.x < 450 and 325 < event.y < 375: tahvel.delete("all") klõps=1 ruudustik() elif klõps==1: värvi(event.x, event.y) def ruudustik(): a=100 b=0 global laius, kõrgus # 绘制细网格线 while a < laius*20 + 120: tahvel.create_line(a, b, a, laius*20 + 100) a +=20 a=0 b=100 while b < kõrgus*20 +120: tahvel.create_line(a, b, kõrgus*20 +100, b) b +=20 # 绘制粗网格线 a=100 b=0 while a < laius*20 +120: tahvel.create_line(a, b, a, laius*20 +100, width=5) a +=100 a=0 b=100 while b < kõrgus*20 +120: tahvel.create_line(a, b, kõrgus*20 +100, b, width=5) b +=100 def värvi(x,y): if 100 <= x <=600 and 100 <= y <=600: col = x//20 -5 row = y//20 -5 if värv[col][row]==0: värv2[col][row] = tahvel.create_rectangle(x//20*20, y//20*20, x//20*20+20, y//20*20+20, fill="black") värv[col][row] =1 elif värv[col][row]==1: tahvel.delete(värv2[col][row]) värv[col][row] =0 raam.bind_all("<1>", hiir) raam.mainloop()
内容的提问来源于stack exchange,提问作者ott vain
相关产品推荐
相关产品推荐

