我有一个Raspberry Pi和一个运行python脚本的RFID扫描器。我使用tkinter通过下面的代码来捕获输入。
from Tkinter import *
import Tkinter as tk
def __init__(self):
command = tk.Tk()
self.e = Entry(command)
self.e.grid()
self.e.focus_set()
command.bind('<KeyPress>', self.key_input)
command.mainloop()
def key_input(self, event):
key_press = event.keysym
if key_press == 'Return':
time.sleep(0.5)
self.enter()
else:
pass
def enter(self):
//various API calls etc. Here is where the RFID tag is often duplicated)我得到了一些奇怪的行为,在触发返回之前,RFID标签被捕获了两次,我想知道这是不是因为操作的顺序。
使用< keypress> vs < keyrelease>的绑定会改变什么吗?或者不是因为这是RFID扫描,而不是用户按键?使用< Return>会更好吗?或者上面的代码也在做同样的事情?
发布于 2018-11-04 23:35:42
发生的情况是,当您按下并按住键时,操作系统会在循环中生成多个按下和释放事件,而不是在按键实际最终释放时生成单个按下和释放事件。因此,只使用Press或Release事件中的一个不会改变任何事情。
一种可能是同时处理Press和Release事件,并在事件处理程序中跟踪键的状态(如果键“被按下”)。现在,这不能按原样解决任何问题,但诀窍是还使用after_idle来推迟Release事件的处理。after_idle计划在下一个事件循环上执行,并在处理其他事件之后执行,因此:
def __init__(self):
...
self.being_pressed = False
command.bind('<KeyPress-Return>', key_input)
command.bind('<KeyRelease-Return>', key_release)
def key_input(self, event):
if not self.being_pressed:
self.enter()
def key_release(self, event):
self.being_pressed = True
self.after_idle(self.do_release, event)
def do_release(self.event):
self.being_pressed = False这样,您仍然可以获得所有按下和释放事件,但因为释放事件现在是在下一个事件循环中处理的,所以如果长时间按键,N+1按下事件处理程序将在N-th释放事件处理程序之前执行,从而将检测到仍在按下该键。
您也可以选择在Press事件处理程序中使用after cancel来完全取消Release事件处理。
https://stackoverflow.com/questions/52994202
复制相似问题