我试图通过在画布上绘制光标来模拟光标并移动它以响应运动事件 .

根据文件"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()