树莓派Guizero应用启动时自动设置TextBox焦点的方法
解决方法
RFID读卡器属于模拟键盘输入的HID设备,仅当目标输入框获得焦点时,读卡器输出的卡号内容才能被TextBox控件接收。程序开机自启时GUI窗口刚完成初始化,默认不会将焦点分配给输入框,因此必须手动点击才能正常读卡。
具体修改逻辑
- guizero的TextBox控件自带
focus()方法可以主动抢占输入焦点,注意不能在控件刚创建时立刻调用——此时窗口还没完成渲染,焦点设置会失效,需要等UI加载完成后再触发。 - 增加容错逻辑:每次识别完卡片清空输入框时,重新给输入框设置焦点,避免后续操作导致焦点丢失、读卡失效。
- 原代码中提示用户点击输入框的文字可以同步删除,不需要用户手动操作。
修改后可直接运行的代码
from gpiozero import LED, Buzzer from guizero import App, Box, Text, TextBox, warn import gpiozero import csv RELAY_PIN = 17 led8 = LED(5) led9 = LED(6) relay= gpiozero.OutputDevice(RELAY_PIN,active_high=False, initial_value=False) def clearDisplay(): print("Clear display") rfidStatus.value = "—" rfidText.value = "" led8.off() led9.off() relay.off() # 清空后重新聚焦输入框,避免焦点丢失 rfidText.focus() rfidStatus.repeat(1000, checkRFidTag) def checkRFidTag(): tagId = rfidText.value.strip() if tagId != "": RFidRegistered = False print(tagId) with open("Database.csv") as csvfile: reader = csv.DictReader(csvfile) for row in reader: if row["RFid"].strip() == tagId: RFidRegistered = True print("Welcome " + row["User"]) rfidStatus.value = "Welcome " + row["User"] led8.on() relay.toggle() rfidStatus.after(5000, clearDisplay) if RFidRegistered == False: print("RFid tag is not registered") rfidStatus.value = "RFid tag is not registered" led9.on() rfidStatus.after(3000, clearDisplay) rfidStatus.cancel(checkRFidTag) app = App(title="RFID EM4100 Simple GUI", width=350, height=150, layout="auto") instructionText = Text(app, text="请直接将RFID卡靠近读卡器即可识别") rfidText = TextBox(app,text="") rfidStatus = Text(app, text="—") rfidStatus.repeat(1000, checkRFidTag) # 窗口加载完成200毫秒后自动给输入框设置焦点 app.after(200, rfidText.focus) app.display()
补充说明
- 延迟时间200毫秒适配常规树莓派系统的启动速度,如果设备加载更慢,可以适当调大到300-500毫秒,只要保证焦点设置在窗口完全显示后执行即可。
- 注意
app.after传入焦点方法时不要加括号,写成rfidText.focus即可,加括号会导致方法立刻执行,达不到延迟加载的效果。 - 代码中额外给卡号读取加了
strip()处理,避免读卡器输出带换行、空格导致的卡号匹配失败问题。
内容的提问来源于stack exchange,提问作者shallnot
相关产品推荐
相关产品推荐

