Android集成Cipherlab硬件扫码器:Kivy应用无法读取条码内容
Kivy Android集成Cipherlab扫码器:条码内容未显示问题解决
问题描述
开发基于Kivy的Android应用,需集成Cipherlab内置硬件扫码器。应用主体已完成,但扫码时存在以下问题:
- 条码以回车键结尾,应用能检测到回车键并触发
TextInput的on_text_validate事件 - 条码的实际内容并未显示在已获焦的
TextInput组件中 - 已在文本编辑器测试扫码器,确认硬件功能正常
重现代码
from kivy.app import App from kivy.lang import Builder from kivy.clock import Clock from kivy.uix.screenmanager import ScreenManager, Screen Builder.load_string(''' <MainScreen>: text_in: text_in memberStatus: memberStatus BoxLayout: orientation: 'vertical' Label: id: memberStatus TextInput: id: text_in multiline: False on_text_validate: root.process_barcode() ''') class MainScreen(Screen): def process_barcode(self): self.memberStatus.text = "Read Value:"+ self.text_in.text self.text_in.text = "" Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True)) def on_enter(self): self.memberStatus.text = "Text Input has focus" Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True)) class MyApp(App): def build(self): sm = ScreenManager() sm.add_widget(MainScreen(name="screen_main")) return sm if __name__ == '__main__': MyApp().run()
解决方案
问题根源在于Cipherlab扫码器模拟键盘输入时,按键事件的传递顺序可能导致on_text_validate先触发,而TextInput的text属性还未完成更新。通过全局监听键盘事件手动收集扫码输入的字符,可确保完整获取条码内容。
修改后的代码如下:
from kivy.app import App from kivy.lang import Builder from kivy.clock import Clock from kivy.uix.screenmanager import ScreenManager, Screen from kivy.core.window import Window Builder.load_string(''' <MainScreen>: text_in: text_in memberStatus: memberStatus BoxLayout: orientation: 'vertical' Label: id: memberStatus TextInput: id: text_in multiline: False ''') class MainScreen(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) self.barcode_buffer = [] # 注册键盘事件监听 self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down=self._on_key_down) def _keyboard_closed(self): self._keyboard.unbind(on_key_down=self._on_key_down) self._keyboard = None def _on_key_down(self, keyboard, keycode, text, modifiers): # 捕获回车键,触发条码处理 if keycode[1] == 'enter': barcode = ''.join(self.barcode_buffer) self.process_barcode(barcode) self.barcode_buffer = [] return True # 阻止事件继续传递,避免干扰其他组件 else: # 收集可打印字符 if text: self.barcode_buffer.append(text) return False def process_barcode(self, barcode): self.memberStatus.text = "Read Value:" + barcode # 保持TextInput焦点,方便下一次扫码 Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True)) def on_enter(self): self.memberStatus.text = "Text Input has focus" Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True)) class MyApp(App): def build(self): sm = ScreenManager() sm.add_widget(MainScreen(name="screen_main")) return sm if __name__ == '__main__': MyApp().run()
关键修改说明
- 全局键盘监听:通过
Window.request_keyboard注册键盘事件监听器,直接捕获扫码器的按键输入 - 字符缓冲:用
barcode_buffer收集扫码输入的每个字符,直到回车键触发处理 - 移除原
on_text_validate绑定:不再依赖TextInput的文本更新事件,避免时机问题
内容的提问来源于stack exchange,提问作者boze
相关产品推荐
相关产品推荐

