我试图通过在画布上绘制光标来模拟光标并移动它以响应运动事件。
根据文档&#34;除了Enter和Leave&#34; 之外,没有按下按钮的鼠标动作没有鼠标事件。但是,Tkinter接受绑定到<Motion>
事件似乎是我想要的事情,除了一件事:你必须首先点击根窗口中的某个地方<Motion>
才能开始射击。一旦指针离开窗口,重新输入而不点击将触发<Enter>
但不会<Motion>
- 即使窗口永远不会失去焦点。
这种行为与我的目标不相符(令人费解的是,为什么会有人想要这样?)所以我写了一个小程序,看看我是否可以改变它,也许是使用event_generate
。我还没有(但),但在这个过程中,我发现Tkinter得到了一些模糊处理鼠标事件。首先,它经常错过<Enter>
和<Leave>
(你将指针移出,它仍然认为它已经进入,反之亦然)。更令人惊讶的是:有时,当您移动指针时,它会触发<Enter>
和一个或两个<Motion>
事件,而不会点击根窗口。然后它变得沉默:在你点击之前不再有<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()