我已经知道您可以将键绑定到小部件,或者将鼠标单击绑定到画布上的元素(例如:矩形、线条等),后者的示例如下:
import tkinter as tk
class App:
def __init__(self, master):
self.master = master
self.canvas = tk.Canvas(master, width=400, height=400)
self.canvas.pack()
# Create the main rectangle
self.rect = self.canvas.create_rectangle(100, 100, 300, 300, fill="white", outline="black")
# Create the three small rectangles inside the main rectangle
self.rect1 = self.canvas.create_rectangle(120, 120, 180, 180, fill="white", outline="black", tags="button1")
self.rect2 = self.canvas.create_rectangle(220, 120, 280, 180, fill="white", outline="black", tags="button2")
self.rect3 = self.canvas.create_rectangle(170, 220, 230, 280, fill="white", outline="black", tags="button3")
# Bind the buttons to the click event and call the hover function
self.canvas.tag_bind("button1", "<Button-1>", lambda event, tag="button1": self.button_click(event, tag))
self.canvas.tag_bind("button2", "<Button-1>", lambda event, tag="button2": self.button_click(event, tag))
self.canvas.tag_bind("button3", "<Button-1>", lambda event, tag="button3": self.button_click(event, tag))
self.canvas.tag_bind("button1", "<Enter>", lambda event, tag="button1": self.hover(event, tag))
self.canvas.tag_bind("button2", "<Enter>", lambda event, tag="button2": self.hover(event, tag))
self.canvas.tag_bind("button3", "<Enter>", lambda event, tag="button3": self.hover(event, tag))
self.canvas.tag_bind("button1", "<Leave>", lambda event, tag="button1": self.leave(event, tag))
self.canvas.tag_bind("button2", "<Leave>", lambda event, tag="button2": self.leave(event, tag))
self.canvas.tag_bind("button3", "<Leave>", lambda event, tag="button3": self.leave(event, tag))
def button_click(self, event, tag):
# Get the coordinates of the clicked rectangle
x1, y1, x2, y2 = self.canvas.coords(tag)
# Create a grey rectangle around the clicked rectangle
self.canvas.delete("clicked")
self.canvas.create_rectangle(x1 - 5, y1 - 5, x2 + 5, y2 + 5, outline="grey", fill="grey", tags="clicked")
def hover(self, event, tag):
# Get the coordinates of the hovered rectangle
x1, y1, x2, y2 = self.canvas.coords(tag)
# Create a grey rectangle around the hovered rectangle
self.canvas.create_rectangle(x1 - 5, y1 - 5, x2 + 5, y2 + 5, outline="grey", tags="hover")
def leave(self, event, tag):
# Remove the grey rectangle when the mouse leaves the rectangle
self.canvas.delete("hover")
root = tk.Tk()
app = App(root)
root.mainloop()
上面的方法适用于将鼠标点击绑定到一个矩形.但后来我注意到,如果我用<KeyPress>
或<Key>
或特定的键替换<Button-1>
,例如<BackSpace>
,它实际上并不起作用.
我一开始以为这是因为没有对准焦点而不起作用,所以我试着使用canvas.focus_set()
,但只有当我使用<Enter>
或<Leave>
时才有效,而使用canvas.tag_bind
:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()
canvas.create_line(10, 10, 100, 100, tags="mytag")
canvas.create_line(10, 20, 100, 80, tags="mytag")
canvas.create_oval(50, 50, 60, 60, fill="black", tags="mytag")
canvas.create_oval(50, 80, 70, 90, fill="blue", tags="no")
canvas.tag_bind("mytag", "<Enter>", lambda event: print("entered element with mytag"))
canvas.tag_bind("mytag", "<Leave>", lambda event: print("leaving element with mytag"))
root.mainloop()
将鼠标悬停在元素上,除了蓝点,似乎是有效的.我发现对绑定键有效的唯一方法是在使用上面的bind_all
键时:
def on_keypress(event):
element_ids = canvas.find_withtag("current")
if element_ids:
print("Key pressed over element:", element_ids)
canvas.tag_bind("mytag", "<Enter>", lambda event: canvas.focus_set())
canvas.tag_bind("mytag", "<Leave>", lambda event: root.focus_set())
canvas.bind_all("<KeyPress>", on_keypress)
编辑:看起来用canvas.bind
代替canvas.bind_all
也行.
但这并不理想,因为我想将单个键绑定到单个"组"元素(例如:它们都共享相同的标签).
除了我自己的非工作try 之外,还有什么方法可以做到这一点吗?