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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:32:04