使用 Kivy 读取条码扫描器

Posted

技术标签:

【中文标题】使用 Kivy 读取条码扫描器【英文标题】:Read Barcode Scanner with Kivy 【发布时间】:2018-11-03 08:38:13 【问题描述】:

我想要实现的是类似于自助结账亭。

所以我想扫描一些条形码。并让 kivy 屏幕显示扫描的项目列表。当我没有要扫描的条形码时,可以按一个按钮并计算所有扫描物品的价格。

我认为最好的方法是使用 while 循环不断询问条形码扫描仪的输入。并且能够通过按下屏幕上的按钮来打破它。

问题是:当循环正在侦听输入时,屏幕上的所有按钮都挂起并且无法按下。所以假设我没有更多要扫描的条形码但因为循环仍在侦听对于输入,整个屏幕挂起。除了终止终端上的整个脚本之外,我什么也做不了。

我应该如何解决这个问题?

这些自助结账亭的工作原理是什么?他们的代码怎么样?

我读到了一些关于 kivy 时钟的建议。但即便如此,当它到达要求输入的代码部分时,它也会挂起。

“选择”、“子处理”或“线程”怎么样?你认为它会解决我的问题吗?但是,即使在阅读之后,我也不知道如何实现它。如果这是正确的方法,您能否建议一些示例代码?

我使用的是 Mac,python 2.7,最终将在带有 LCD 屏幕的树莓派上运行它。

这是我的循环:

def getItem():
    while True:
        answer = input('What is the box ID? ')
        if answer == 999:   # to break out from loop
            break
        elif type(answer) == int:
            display on kivy screen
        else:
            print('Sorry I did not get that')

这是它在 kivy 上的样子:

更新代码:

这是在 kv 文件中:

<ScreenTwo>:
    member_status: memberStatus
    box_no: boxNo
    text_in: textIn
    BoxLayout:
        Label:
            id: memberStatus
            text: '' 
        GridLayout:
            rows: 3
            padding: [100,500]
            spacing: 10
            BoxLayout:
                Label:
                    id: boxNo
                    text: ''
            BoxLayout:
                TextInput:
                    id: textIn
                    write_tab: False
                    multiline: False
                    on_text_validate:
                        root.sayHello()
                        self.text = ""
                        self.focus = True
                        #also tried root.inputFocus()
            BoxLayout:
                CustButton:
                    text: "Done"
                    on_press:
                        root.manager.transition.direction = "right"
                        root.manager.current = 'menu'
                        root.clearField()

这是在 py 文件中:

class ScreenTwo(Screen):
    text_in = ObjectProperty(None)

    def inputFocus(self):
        self.manager.screen_two.text_in.focus = True

【问题讨论】:

为什么使用终端而不使用TextInput? @eyllanesc 会解决问题吗? 显然,我的问题是为什么要使用这样古老而丑陋的东西:input() 如果 GUI 提供现代而美丽的东西:TextInput() .输入是阻塞的,因为它们阻止程序前进并且不让 GUI 遵循其事件循环。事件循环是检查鼠标等其他事件所必需的。为您提供时钟解决方案的人不知道 GUI 应该如何工作,或者正在强制使用错误的解决方案。 @eyllanesc 哈哈哈,因为我是新手。好的,我有点理解你。但是我可以澄清一下:使用 textinput 列,当条形码扫描到 textinput 时,它是否可以检测到有输入并自动运行功能? 是的,条形码扫描仪在执行结束时生成一个输入 ("\n"),因此 input() 对您有效,您必须使用 on_text_validate 事件,但为此您必须设置多行属性为 False,更多信息请阅读以下内容:***.com/questions/12037379/… 【参考方案1】:

您不应该强求,input() 是一个阻止函数,它不允许 GUI 在事件循环中运行,事件循环允许 GUI 能够查看其他事件并执行其他任务,例如鼠标,所以你的应用程序被冻结了。

如果您可以使用TextInput,为什么还要使用input()您必须使用 GUI 为您提供的内容,因为它可以与 GUI 一起使用。

条形码扫描器在建立文本结束时发送一个输入,必须通过事件on_text_validate 使用,在这种情况下,您必须在标签中设置文本,然后清理文本并在最后获得焦点,对于最后一项任务,您必须使用在下一次迭代中执行此任务的时钟。

在下一节中,我将展示一个最小的示例。

import kivy

from kivy.app import App
from kivy.lang import Builder

from kivy.clock import Clock

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen

Builder.load_string('''
<ScreenTwo>:
    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 ScreenTwo(Screen):
    def process_barcode(self):
        self.memberStatus.text = self.text_in.text
        self.text_in.text = ""
        Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True))

class MyApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(ScreenTwo(name="screen_two"))
        return sm

if __name__ == '__main__':
    MyApp().run()

【讨论】:

像魅力一样工作!

以上是关于使用 Kivy 读取条码扫描器的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:如何最好地读取手持条码扫描仪?

Unity UWP 蓝牙条码扫描器

条码扫描枪输入为啥不能用键盘输入代替

条码Code39扫描可靠吗?

扫描 CA 彩票条码?

如何在ipod中使用前置摄像头进行条码扫描