我应该使用<keypress>或<keyrelease>(或<Return>)进行RFID扫描吗?

Cra*_*rce 5 python tkinter

我有一个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)
Run Code Online (Sandbox Code Playgroud)

我得到一些奇怪的行为,其中RFID标签在返回被触发之前被捕获两次并且我想知道它是否是由于操作的顺序.

使用<keypress> vs <keyrelease>进行绑定会改变什么吗?或者不是因为它是RFID扫描而不是用户按键?使用<Return>会优惠吗?或者上面的代码完成了同样的事情?

Tim*_*mur 0

发生的情况是,当您按住该键时,操作系统会循环生成多个 Press 和 Release 事件,而不是当该键实际最终释放时一次 Press 和 Single 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
Run Code Online (Sandbox Code Playgroud)

这样,您仍然可以获得所有 Press 和 Release 事件,但是因为 Release 事件现在在下一个事件循环中处理,如果长时间按下按键,N+1Press 事件处理程序将在第 -th Release 事件处理程序之前执行N,因此将检测到该键仍在被按下。

或者,您还可以after cancel在 Press 事件处理程序中使用来完全取消 Release 事件处理。