Tkinter鼠标指针无法悬停在按钮上



我在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

在对您的代码进行实验后,我做出了以下观察:

  1. Motion事件绑定到根时,(event.x, event.y)返回窗口中任何像素相对于像素所在的小部件的坐标。对应的小部件(不是root(的左上角被取为(0,0(
  2. 如果将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()

最新更新