kivy:屏幕切换时如何在没有挂屏的情况下运行循环功能?

时间:2018-05-23 08:40:57

标签: python python-2.7 kivy

我想要实现的目标:当屏幕从ScreenOne切换到ScreenTwo时,运行一个' while循环'功能,直到按下ScreenTwo上的按钮并打破循环。

此功能应该从连接到我的计算机的条形码扫描仪运行和接收输入(含义,输入是条形码),并使用扫描的条形码数量更新ScreenTwo上的标签。

然后,一旦我没有更多条形码进行扫描,请按"完成" ScreenTwo上的按钮 - 应该发送输入" 999"打破循环功能。

我在屏幕切换时尝试运行功能的方法:使用' on_enter'

class ScreenTwo(Screen):
    def on_enter(self):
        getStatus()
        updatePoints()

我面临的问题:

  1. 屏幕从ScreenOne切换到ScreenTwo,功能运行(我看到它发生在Mac终端上) BUT ScreenTwo上的按钮无法按下(Mac色轮旋转)
  2. 我还没弄明白如何完成"完成"按钮发送输入' 999'打破循环的功能。
  3. 如何解决1?

    如何实现2?

    以下分别是ScreenOne和ScreenTwo的截图: Screenshot of ScreenOne Screenshot of ScreenTwo

    这里是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()
    

    这是returnStationLayout2.kv

    "完成"按钮(在ScreenTwo中)位于脚本的底部。

    当屏幕切换到ScreenTwo时,无法按下它。 我希望在按下时,它可以输入	 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()
    

1 个答案:

答案 0 :(得分:1)

解决方案

此答案基于问题中的评论部分中的讨论。下面的代码是在扫描条形码时扫描器发送特定信号的假设下编写的。总体思路是在发送信号后运行一个函数。

时钟周期

我建议熟悉kivy的Clock对象。可以创建一个侦听器函数来检查信号是否每n秒发送一次。确切地说,让我们说你想在检测到信号后运行process()功能。如果成功扫描条形码并创建一个监听器来检查信号是否已发送,那么我们还会声明一个变量scanned来存储信息(因此请检查scanned变量是否成立{{1} })。以下代码示例将True变量每隔2秒设置为scanned以模拟扫描行为。

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()