Python 基维:当屏幕切换而没有挂屏时,如何运行循环功能?

Python 基维:当屏幕切换而没有挂屏时,如何运行循环功能?,python,python-2.7,kivy,Python,Python 2.7,Kivy,我想实现的是:当屏幕从ScreenOne切换到ScreenII时,运行“while loop”功能,直到ScreenII上的按钮被按下并中断循环 该功能应该运行并接收连接到我的计算机上的条形码扫描仪的输入。这意味着,输入是条形码,并用扫描的条形码数量更新屏幕2上的标签 然后,当我没有更多的条形码要扫描时,按屏幕2上的“完成”按钮——这将发送输入999以中断循环功能 屏幕切换时我如何运行函数:使用“on_enter” class ScreenTwo(Screen): def on_ente

我想实现的是:当屏幕从ScreenOne切换到ScreenII时,运行“while loop”功能,直到ScreenII上的按钮被按下并中断循环

该功能应该运行并接收连接到我的计算机上的条形码扫描仪的输入。这意味着,输入是条形码,并用扫描的条形码数量更新屏幕2上的标签

然后,当我没有更多的条形码要扫描时,按屏幕2上的“完成”按钮——这将发送输入999以中断循环功能

屏幕切换时我如何运行函数:使用“on_enter”

class ScreenTwo(Screen):
    def on_enter(self):
        getStatus()
        updatePoints()
我面临的问题:

屏幕从ScreenOne切换到ScreenTwo,功能运行我看到它发生在Mac终端上,但是ScreenTwo上的按钮不能被按下,Mac色轮旋转。 我还没有弄明白如何让“完成”按钮向函数发送输入“999”来打破循环。 如何解决1

如何实现2

下面是屏幕一和屏幕二的截图:

这是returnStation2.py文件

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty


def getStatus():
    while True:
        answer = input('What is the box ID? ')
        if answer == 999: #LOOPS BREAK WHEN INPUT IS 999
            break
        elif type(answer) == int:
            do something
        else:
            print('Sorry I did not get that')

def updatePoints():
    do something

class ScreenManagement(ScreenManager):
    screen_one = ObjectProperty(None)
    screen_two = ObjectProperty(None)

class ScreenOne(Screen):
    member_status = ObjectProperty(None)

    def backspace(self, textString):
        newTextString = textString[0:-1]
        self.display.text = newTextString

    def getPoints(self, phoneNumber):
        self.manager.screen_two.member_status.text = phoneNumber

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

    def on_enter(self):
        getStatus()
        updatePoints()

    def clearField(self):
        self.manager.screen_one.input_text.text = ""

class ReturnStationLayout2App(App):

    def build(self):
        return ScreenManagement()


if __name__ == '__main__':
    ReturnStationLayout2App().run()
这是2.kv外的回流站

屏幕2中的“完成”按钮位于脚本的底部

当屏幕切换到屏幕2时,无法按下该按钮。 我希望当按下时,它可以输入“999”来中断正在运行的循环函数

<ScreenManagement>:
    screen_one: screen_one
    screen_two: screen_two

    ScreenOne:
        id: screen_one
        name: 'menu'
    ScreenTwo:
        id: screen_two
        name: 'settings'

<CustButton@Button>:
    font_size: 32

<ScreenOne>:
    input_text : entry
    GridLayout:
        id: numberPad
        rows: 5
        padding: [300,200]
        spacing: 10

        # Where input is displayed
        BoxLayout:
            Label:
                text: "+65"
                font_size: 50
                size_hint: 0.2, 1
            TextInput:
                id: entry
                font_size: 50
                multiline: False
                padding: [20, ( self.height - self.line_height ) / 2]


        BoxLayout:
            spacing: 10
            CustButton:
                text: "1"
                on_press: entry.text += self.text
            CustButton:
                text: "2"
                on_press: entry.text += self.text
            CustButton:
                text: "3"
                on_press: entry.text += self.text
            CustButton:
                text: "DEL"
                on_press: root.backspace(entry.text)

        BoxLayout:
            spacing: 10
            CustButton:
                text: "4"
                on_press: entry.text += self.text
            CustButton:
                text: "5"
                on_press: entry.text += self.text
            CustButton:
                text: "6"
                on_press: entry.text += self.text
            CustButton:
                text: "AC"
                on_press: entry.text = ""

        BoxLayout:
            spacing: 10
            CustButton:
                text: "7"
                on_press: entry.text += self.text
            CustButton:
                text: "8"
                on_press: entry.text += self.text
            CustButton:
                text: "9"
                on_press: entry.text += self.text
            CustButton:
                text: "Enter" #HERE IS THE ENTER BUTTON
                on_press:
                    root.manager.transition.direction = 'left'
                    root.manager.transition.duration = 1
                    root.manager.current = 'settings'
                    root.getPoints(entry.text)

        BoxLayout:
            spacing: 10
            Label:
                text: ""
            CustButton:
                text: "0"
                on_press: entry.text += self.text
            Label:
                text: ""
            Label:
                text: ""

<ScreenTwo>:
    member_status: memberStatus
    BoxLayout:
        Label:
            id: memberStatus
            text: ''  
        GridLayout:
            rows: 3
            padding: [100,500]
            spacing: 10
            BoxLayout:
                Label:
                    text: "You have scanned:"
            BoxLayout:
                CustButton:
                    text: "Done" #THIS IS THE BUTTON I HOPE TO BE ABLE TO BREAK THE LOOP FUNCTION
                    on_press:
                        root.manager.transition.direction = "right"
                        root.manager.current = 'menu'
                        root.clearField()
解决方案 此答案基于问题下方评论部分的讨论。下面的代码是在假定扫描仪在扫描条形码时发送特定信号的情况下编写的。总体思路是在发送信号后运行函数

时钟周期 我建议你熟悉一下kivy的物体。可以创建一个侦听器函数来检查信号是否每n秒发送一次。确切地说,假设您希望在检测到信号后运行process函数。我们还要声明一个扫描的变量来存储条形码成功扫描时的信息,并创建一个侦听器来检查信号是否已发送,以便检查扫描的变量是否为真。下面的代码示例将扫描变量每2秒设置为True,以模拟扫描行为

from kivy.app import App
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen

# Define constants and the scanned variable, for easy example
INTERVAL = 0.01
scanned = False


# Process method runs every 0.01 seconds, note the use of dt argument (explained in docs)
def process(dt):
    # Retrieve the global variable, for easy example
    global scanned
        
    # Check if scanned, note setting scanned to False once an item was scanned.
    # Here you can also check the uniqueness of the scanned barcode (to avoid having the same barcode processed many times)
    if scanned is True:
        print("Scanned! Processing the data and setting scanned to False.")
        scanned = False
    else:
        print("Not scanned yet!")


# Mimic scanning behaviour
def scan(dt):
    # Retrieve the global variable and set it to true 
    global scanned
    scanned = True


class Main(App):

    def __init__(self):
        super(Main, self).__init__()
        
        # Schedule the functions to be called every n seconds
        Clock.schedule_interval(process, INTERVAL)
        Clock.schedule_interval(scan, INTERVAL*200)

    def build(self):
        # Display screen with a single button for easy example
        scr = Screen()
        btn = Button(text="You can press me but nothing will happen!")
        scr.add_widget(btn)
        return scr


if __name__ == '__main__':
    Main().run()
输出:

Not scanned yet!
.
.
.
Not scanned yet!
Scanned! Processing the data and setting scanned to False.

一旦您启动while循环,它将一直运行,直到您打破它,并阻止所有其他行为。也就是说,当代码运行时,您将无法单击该按钮,并且无法更新屏幕。您可以尝试创建一个独立于应用程序其他部分的独立线程,但我相信Python的输入将阻止一切,因为它的创建方式我希望有人在这方面支持我。除此之外,当我运行代码时,按钮被其他元素覆盖,我必须首先将网格布局的填充更改为[100100]。可以使用kivy每n秒调用一个函数,也可以使用kivy的输入来不使用输入。这就足以解决你的问题了吗?@Kacper Florianński有没有办法让循环同时监听屏幕按钮和我的条形码扫描仪的输入?我想实现的是,一个用户要扫描任意数量的条形码,这就是为什么循环要听更多的输入,如果有的话,一旦他完成扫描,按下“完成”按钮,并打破循环。有什么办法吗?最简单的方法是添加一个添加按钮,必须按下该按钮才能添加条形码。请注意,即使使用python的输入,也需要在每次输入后按enter键。如果条形码是从键盘输入的,您可以要求用户以特定格式输入所有条形码,然后从中提取值。若它们是图形对象,你们可以不用按任何按钮就可以进行扫描。例如,让用户在不移动手机的情况下等待1秒,以便扫描条形码。@Kacperflorianński我想到的是一个图书馆借阅亭。它如何允许用户扫描他们打算借阅的任意数量的书籍,然后单击信息亭屏幕上的“完成”以处理所有已扫描书籍的借阅?我可以问一下,在间隔期间,屏幕上的按钮仍将起作用吗?他们还能继续工作吗?是的,他们仍能正常工作。让我编辑答案并添加一个按钮。我添加了这个按钮以显示应用程序将保持响应。哇,太棒了!我认为这将适用于我的应用程序:我将尝试看看如何将其放入我的代码中。我在这方面做得很差,但谢谢你迄今为止对我的帮助!我真的很感激!别担心,我真的很喜欢你的项目,继续做好: