如何在PySimpleGUI输入框中捕获带CRLF结尾的扫描枪输入
问题:PySimpleGUI无法捕获扫码枪带CRLF结尾的输入
问题描述
我用PySimpleGUI编写了一段代码,希望捕获扫码枪扫描带CRLF(\r\n)结尾的二维码数据,但始终无法打印带结束信号的内容。手动输入"fffff\r\n"时能正常打印,但扫码枪扫描带CRLF结尾的二维码时却不行,只能读取无结束信号的数据。请问这是PySimpleGUI的问题吗?该怎么解决?
原始代码
import PySimpleGUI as sg import time import datetime sg.theme('DarkAmber') layout = [[sg.Text('data:'), sg.Input(key='-IN-', enable_events=True)], [sg.Text(size=(40, 1), key='-TIME-')], [sg.Button('Exit')]] window = sg.Window('test input', layout) text = '' while True: event, values = window.read(0) if event == sg.WIN_CLOSED or event == 'Exit': break elif event == '-IN-': text += values['-IN-'] elif event == '__TIMEOUT__': if text.endswith('\r\n'): print(f'{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - {text}') text = '' else: print(event) window['-TIME-'].update(f'time:{time.time()}') window.close()
问题原因
不是PySimpleGUI的问题,是你的输入处理逻辑有误:
- 扫码枪的输入是模拟键盘快速连续输入字符+CRLF,PySimpleGUI的Input组件每输入一个字符就会触发一次
-IN-事件。 - 你每次都把
values['-IN-'](当前输入框的完整内容)追加到text变量,导致内容重复累加(比如输入第一个'f'时text是'f',输入第二个'f'时values['-IN-']是'ff',text变成'fff'),最终text无法正确匹配\r\n结尾。 - 手动输入
"fffff\r\n"是一次性输入完整内容,所以values['-IN-']是完整的目标字符串,追加后能触发判断。
解决方案
方案一:直接监听输入框完整内容(简单高效)
直接检测输入框内容是否包含CRLF,处理后清空输入框避免重复触发:
import PySimpleGUI as sg import datetime sg.theme('DarkAmber') layout = [[sg.Text('data:'), sg.Input(key='-IN-', enable_events=True)], [sg.Text(size=(40, 1), key='-TIME-')], [sg.Button('Exit')]] window = sg.Window('test input', layout) while True: event, values = window.read(timeout=100) if event == sg.WIN_CLOSED or event == 'Exit': break elif event == '-IN-': input_content = values['-IN-'] # 检测是否包含CRLF结尾 if '\r\n' in input_content: # 提取有效数据(去掉CRLF) data = input_content.rstrip('\r\n') print(f'{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - {data}') # 清空输入框,避免重复处理 window['-IN-'].update('') # 更新时间显示 window['-TIME-'].update(f'time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}') window.close()
方案二:跟踪输入增量(精准处理字符流)
通过记录输入框内容的长度变化,只累加新增的字符,避免重复:
import PySimpleGUI as sg import datetime sg.theme('DarkAmber') layout = [[sg.Text('data:'), sg.Input(key='-IN-', enable_events=True)], [sg.Text(size=(40, 1), key='-TIME-')], [sg.Button('Exit')]] window = sg.Window('test input', layout) previous_length = 0 text_buffer = '' while True: event, values = window.read(timeout=100) if event == sg.WIN_CLOSED or event == 'Exit': break elif event == '-IN-': current_content = values['-IN-'] # 计算本次新增的字符 new_chars = current_content[previous_length:] text_buffer += new_chars previous_length = len(current_content) # 检测是否以CRLF结尾 if text_buffer.endswith('\r\n'): data = text_buffer.rstrip('\r\n') print(f'{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - {data}') text_buffer = '' previous_length = 0 window['-IN-'].update('') # 更新时间显示 window['-TIME-'].update(f'time:{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}') window.close()
说明
两种方案都能适配扫码枪的快速输入场景:
- 方案一逻辑简单,适合只需要完整数据的场景;
- 方案二更精准,适合需要中间处理部分输入的场景;
- 无需依赖
__TIMEOUT__事件,-IN-事件足以捕获扫码枪的连续输入。
内容的提问来源于stack exchange,提问作者Super 柒
相关产品推荐
相关产品推荐

