我试图通过在画布上绘制光标来模拟光标并移动它以响应运动事件 .
根据文件"there is no mouse event for mouse motion without pressing a button, except for Enter and Leave" . 但是,Tkinter接受绑定到 <Motion>
事件,这似乎是我想要的事情,除了一件事:你必须首先点击根窗口中的某个地方 <Motion>
才能开始射击 . 一旦指针离开窗口,重新进入而不点击将触发 <Enter>
但不会 <Motion>
- 即使窗口永远不会失去焦点 .
这种行为与我的目标不相符(令人费解的是,为什么有人想要这样?)所以我写了一个小程序,看看我是否可以改变它,也许是通过使用 event_generate
. 我还不能(但),但在这个过程中,我发现Tkinter得到了一些模糊处理鼠标事件 . 首先,它经常错过 <Enter>
和 <Leave>
(你将指针移出,它仍然认为它在,反之亦然) . 更令人惊讶的是:有时,当您移动指针时,它会触发 <Enter>
和一个或两个 <Motion>
事件 without clicking in the root window . 然后它变得沉默:在你点击之前不再有 <Motion>
事件 . 您可以使用下面的代码重现这些问题 . 我正在运行OS X El Capitan,Python 2.7 .
对这些行为的任何解释,或者如何在不点击的情况下跟踪运动事件的想法将不胜感激 .
from Tkinter import *
def enter(e):
if e.widget is not canvas:
print "<Enter> caught by", e.widget
if canvas.state != "outside":
print "<Enter> in 'inside' state!"
canvas.state = "inside"
canvas.n = 0
canvas.itemconfig(inout, text=canvas.state)
canvas.itemconfig(count, text="no motions yet")
canvas.event_generate('<Button-1>', x=e.x, y=e.y, state=0x0100)
#canvas.update()
def motion(e):
if canvas.state == "outside":
print "<Motion> in 'outside' state!"
canvas.n += 1
canvas.itemconfig(count, text="motions since enter: {:03d}".format(canvas.n))
#canvas.update()
def leave(e):
if e.widget is not canvas:
print "Leave caught by", e.widget
if canvas.state == "outside":
print "<Leave> in 'outside' state!"
canvas.state = "outside"
canvas.itemconfig(inout, text=canvas.state)
canvas.itemconfig(count, text="")
#canvas.update()
root = Tk()
frame = Frame(root)
frame.pack(fill=BOTH)
canvas = Canvas(frame, bg='#E4E4E4', highlightthickness=0)
canvas.grid(row=0, column=0, sticky=W+E+N+S)
canvas.create_text(140, 20, text="(tracking <Enter>, <Motion>, <Leave>)")
inout = canvas.create_text(140, 100, text="outside")
count = canvas.create_text(140, 120, text="")
canvas.n = 0
canvas.state = "outside"
canvas.bind('<Enter>', enter)
canvas.bind('<Motion>', motion)
canvas.bind('<Leave>', leave)
canvas2 = Canvas(frame, height=100, highlightthickness=0)
canvas2.grid(row=1, column=0, sticky=W+E)
canvas2.create_text(140, 50, text="(no tracking here)")
frame.rowconfigure(0, weight=1)
def focusout(e):
print "root lost focus"
root.bind('<FocusOut>', focusout)
root.mainloop()