【发布时间】:2019-10-15 17:25:31
【问题描述】:
环境:macOS Catalina、Python 3.7.4、Tcl/Tk 8.6.9、VSC 1.39.1
我有一种情况,我使用条形码/二维码扫描仪向 ttk.Entry() 方法提供字符串,然后触发一个函数。
阅读器被操作系统视为一个 HID 键盘,因此来自 QR 码的文本由我在代码执行期间关注的 ttk.Entry() 小部件接收。我已将小部件绑定到键,因为扫描仪会在文本字符串的末尾发送一个 cr/lf,它可以根据需要工作。
但是,我遇到了一个问题,如果 qr 码在扫描仪上停留的时间过长,它将重新扫描 qr 码,并且小部件会再次收到 qr 码文本,这会导致它再次被处理。
我尝试在函数中禁用 ttk.Entry(),删除小部件内容,并删除焦点无济于事。即使小部件被禁用并且没有焦点,我看到的行为也会发生,如果扫描仪在函数执行时重新扫描二维码,它仍然会获取输入并再次执行函数。
在第一个示例中,我只是尝试禁用小部件,但这不起作用。小部件在函数中仍会获得稍后的扫描。
# test-ttk-entry1.py
import time
import tkinter as tk
from tkinter import StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.configure(state="disabled")
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
第二次尝试是禁用条目小部件,并在再次激活后删除字段中的文本。
# test-ttk-entry2.py
import time
import tkinter as tk
from tkinter import END, StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.delete(0, END)
kbEntry.configure(state="disabled")
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbEntry.delete(0, END)
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
最后,我正在阅读有关从小部件获取焦点并将焦点赋予根窗口的信息,所以我添加了它,它仍然会多次打印到控制台,就像 ttk.Entry 正在读取键盘缓冲区一样() 小部件。奇怪的是,小部件在被禁用时似乎通常不会响应对方法的任何调用,但似乎 ttk.Entry() 小部件的属性/属性(如果我的 OOP 术语不正确,请原谅)可以被操纵禁用时。
# test-ttk-entry2.py
import time
import tkinter as tk
from tkinter import END, StringVar, ttk
root = tk.Tk()
def print_text(event):
global kbEntry
textValue = kbEntry.get()
kbEntry.delete(0, END)
kbEntry.configure(state="disabled")
root.focus_set()
time.sleep(2) # Add in a delay to allow for repeat scan
print(textValue)
time.sleep(2) # Add in a delay to allow for repeat scan
kbEntry.configure(state="active")
kbEntry.delete(0, END)
kbEntry.focus_set()
kbText = StringVar()
kbEntry = ttk.Entry(root, width=10, textvariable=kbText)
kbEntry.bind("<Return>", print_text)
kbEntry.pack()
kbEntry.focus_set()
root.mainloop()
那么,当我的函数正在执行时,如何防止 ttk.Entry() 小部件接受来自 HID/键盘设备的任何输入?
【问题讨论】:
-
如果我在函数内对 kbEntry.get() 执行后续调用,则缓冲区为空。但是一旦该功能完成,Entry 小部件就会开始对 QR 码进行后续扫描,就像它在缓冲区中等待并且 Entry 小部件看到它并重新触发事件一样。
-
您可以通过在输入字段中快速输入“1234”
来查看此操作。这也需要是非阻塞的。 -
我一直在搞乱 .pack_forget() 试图阻止 .Entry() 小部件接收多个(重复)条目,但到目前为止,这并不是最好的。我想我会编写我的回调来保存一个全局字符串变量,并在连续调用时检查它是否存在重复条目并忽略额外的条目。
标签: python-3.x tkinter tkinter-entry