使用根与其他小工具绑定
我在Python Tkinter中的鼠标指针有问题。
我有以下代码:
import tkinter as tk
root = tk.Tk()
def motion(event):
x, y = window_canvas.canvasx(event.x), window_canvas.canvasy(event.y)
print('{}, {}'.format(x, y))
window_canvas = tk.Canvas(root, borderwidth=0, background="white", width = 300, height = 300, highlightthickness=0)
window_canvas.pack(fill='both')
window_frame = tk.Frame(window_canvas, background='red', borderwidth=0, width = 300, height = 300)
window_frame.pack()
button = tk.Button(window_frame, text=' ', borderwidth=1, highlightbackground='#9c9c9c', bg='black')
button.place(x=50, y=50)
root.bind('<Motion>', motion)
root.mainloop()
不,我想,我的鼠标相对于红色边框的正确坐标已经打印出来了。然而,当我将鼠标悬停在按钮上时,坐标会发生变化,不再根据红色window_frame表示实际坐标。
有人有解决方案吗?
使用根与其他小工具绑定Motion
:
在对您的代码进行实验后,我做出了以下观察:
- 当
Motion
事件绑定到根时,(event.x, event.y)
返回窗口中任何像素相对于像素所在的小部件的坐标。对应的小部件(不是root
(的左上角被取为(0,0( - 如果将
Motion
事件绑定到特定的小部件,则(event.x, event.y)
仅在像素直接存在于小部件内部时返回像素的坐标(相对于小部件(。如果您将鼠标悬停在子窗口小部件上,则不会打印任何内容
解决方案:
现在,说到您的问题,当鼠标悬停在按钮上时,您无法直接从(event.x, event.y)
计算画布坐标。您必须进行以下转换。
window_coords = topleft_button_coordinates + (event.x, event.y)
canvas_coords = canvas.canvasx(window_coords.x), canvas.canvasy(window_coords.y)
只有当坐标相对于按钮时,才能执行上述转换。您可以使用event.widget
属性来检查事件是否由按钮触发。
按钮左上角的坐标(相对于画布(可以使用.winfo_x()
和.winfo_y()
获得。
工作代码:
import tkinter as tk
root = tk.Tk()
def motion(event):
global button
convx, convy = event.x, event.y
if event.widget == button:
convx, convy = button.winfo_x() + event.x, button.winfo_y() + event.y
x, y = window_canvas.canvasx(convx), window_canvas.canvasy(convy)
print('{}, {}'.format(x, y))
window_canvas = tk.Canvas(root, borderwidth=0, background="white", width = 300, height = 300, highlightthickness=0)
window_canvas.pack(fill='both')
window_frame = tk.Frame(window_canvas, background='red', borderwidth=0, width = 300, height = 300)
window_frame.pack()
button = tk.Button(window_frame, text=' ', borderwidth=1, highlightbackground='#9c9c9c', bg='black')
button.place(x=50, y=50)
root.bind('<Motion>', motion)
root.mainloop()