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

Posted

技术标签:

【中文标题】我应该使用 <keypress> 和 <keyrelease>(或 <Return>)进行 RFID 扫描吗?【英文标题】:Should I use <keypress> or <keyrelease> (or <Return>) for RFID scanning? 【发布时间】:2019-03-30 08:33:58 【问题描述】:

我有一个 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 标签,我想知道这是否是因为操作顺序。

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

【问题讨论】:

请用一些可用的代码更新您的问题。只需查看您的代码,我就可以看到您已经使用至少 2 种不同的方法导入了 tkinter。应该避免这种情况。我看到的第二个问题是您的 key_input 方法在 tkinter 主循环之外。我猜你正在学习一个类的一小部分,然后把它扔到这个例子中,但这对测试代码没有多大帮助。老实说,不是 100% 你的问题是什么。您的 RFID 扫描会向您发送某种信号,因此请在检查事件时使用它。 为什么要将事件绑定到 Tk 对象而不是 Entry 对象? 您能否使用打印语句来检测您的扫描仪正在触发什么样的按键事件?然后继续使用该事件名称。 @DaveMaheux 我是 python 和 tkinter 的新手,应该如何设置?该代码大部分时间都可以正常工作,只是偶尔会失败,我认为这可能就是问题所在。 @Craig.Pearce 如果您的代码大部分时间都可以工作,但有时会失败,那么您应该保留正在通过的事件的运行日志,然后在失败时查看该日志 【参考方案1】:

发生的情况是,当您按住键时,操作系统会在循环中生成多个 Press and Release 事件,而不是在实际最终释放键时生成单个 Press and Single Release。因此,仅使用 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

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

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

【讨论】:

以上是关于我应该使用 <keypress> 和 <keyrelease>(或 <Return>)进行 RFID 扫描吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 KeyPress 中拦截“Q”和公司

.keypress 在 DIV 标签上?

AngularJS:ng-keypress 不起作用

jQuery基础:keydown( ) 与 keypress( ) 区别

替换已弃用的 `keypress` DOM 事件

求C# KeyPress 事件中,所有e.KeyChar值的意思