Tkinter对鼠标事件的不稳定处理

时间:2016-10-23 23:25:45

标签: python tkinter event-handling mouseevent

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

根据文档&#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()

0 个答案:

没有答案