Tkinter Canvas圆形点击变色的条件逻辑实现问题
Tkinter Canvas圆形点击变色的条件逻辑实现问题
看起来你是想实现点击Canvas上的圆形就修改它的填充色,但目前代码里有个小问题,而且你疑惑该怎么用if else来处理不同圆形的变色逻辑对吧?我来一步步帮你解决。
首先先修正你当前代码的核心错误:你在object_click_event里用了event.num,但Tkinter的鼠标点击事件对象根本没有num这个属性,运行时肯定会触发AttributeError。要获取被点击的图形ID,我们有两种常用方法:
方法1:不需要if else,统一修改所有点击圆形的颜色
如果你的需求只是「不管点击哪个圆,都把它变成蓝色」,那完全不需要if else,只需要修正获取图形ID的方式即可。可以用event.widget.find_withtag(tk.CURRENT)来获取当前被点击的图形,代码修改如下:
import tkinter as tk class CanvasEvents(tk.Tk): def __init__(self): super().__init__() self.geometry('510x510+700+100') self.title("Event") self.canvas = tk.Canvas(self, bg='grey', width=500, height=500) self.canvas.pack(pady=5) kor1 = self.canvas.create_oval(20, 20, 100, 100, width=2, fill="orange") kor2 = self.canvas.create_oval(220, 20, 300, 100, width=2, fill="red") kor3 = self.canvas.create_oval(420, 20, 500, 100, width=2, fill="green") self.canvas.tag_bind(kor1, '<Button-1>', self.object_click_event) self.canvas.tag_bind(kor2, '<Button-1>', self.object_click_event) self.canvas.tag_bind(kor3, '<Button-1>', self.object_click_event) def object_click_event(self, event): # 获取被点击的图形ID clicked_item = event.widget.find_withtag(tk.CURRENT)[0] self.canvas.itemconfigure(clicked_item, fill="blue") print('Clicked object at: ', self.canvas.coords(clicked_item), clicked_item) if __name__ == "__main__": ablak = CanvasEvents() ablak.mainloop()
方法2:用if else实现不同圆形的差异化变色
如果你想让不同的圆形点击后变成不同的颜色(比如橙色圆变蓝色、红色圆变绿色、绿色圆变回橙色),这时候就需要if else来判断被点击的是哪个图形。我们可以先把三个圆形的ID保存为类的实例属性,方便在事件函数中判断:
import tkinter as tk class CanvasEvents(tk.Tk): def __init__(self): super().__init__() self.geometry('510x510+700+100') self.title("Event") self.canvas = tk.Canvas(self, bg='grey', width=500, height=500) self.canvas.pack(pady=5) # 把圆形ID保存为实例属性,方便后续判断 self.kor1 = self.canvas.create_oval(20, 20, 100, 100, width=2, fill="orange") self.kor2 = self.canvas.create_oval(220, 20, 300, 100, width=2, fill="red") self.kor3 = self.canvas.create_oval(420, 20, 500, 100, width=2, fill="green") self.canvas.tag_bind(self.kor1, '<Button-1>', self.object_click_event) self.canvas.tag_bind(self.kor2, '<Button-1>', self.object_click_event) self.canvas.tag_bind(self.kor3, '<Button-1>', self.object_click_event) def object_click_event(self, event): clicked_item = event.widget.find_withtag(tk.CURRENT)[0] # 根据不同的图形ID设置不同的填充色 if clicked_item == self.kor1: self.canvas.itemconfigure(clicked_item, fill="blue") elif clicked_item == self.kor2: self.canvas.itemconfigure(clicked_item, fill="green") elif clicked_item == self.kor3: self.canvas.itemconfigure(clicked_item, fill="orange") print('Clicked object at: ', self.canvas.coords(clicked_item), clicked_item) if __name__ == "__main__": ablak = CanvasEvents() ablak.mainloop()
补充说明:
tk.CURRENT是Tkinter的内置标签,代表当前鼠标下的图形元素;- 如果你的Python版本是3.10及以上,也可以用更简洁的
match-case语句替代if else,逻辑是一样的; - 另外还有一种更简便的绑定方式:绑定事件时直接把图形ID作为参数传递给事件函数,这样就不用在函数里再查找了,比如:
然后事件函数改成接受两个参数:self.canvas.tag_bind(kor1, '<Button-1>', lambda e: self.object_click_event(e, kor1))def object_click_event(self, event, item_id):,这样直接用item_id操作就行。
备注:内容来源于stack exchange,提问作者user12405218
相关产品推荐
相关产品推荐

