kivy:如何在屏幕切换不挂屏的情况下运行循环功能? [英] kivy: how to run loop function when screen switches without hanging screen?

查看:169
本文介绍了kivy:如何在屏幕切换不挂屏的情况下运行循环功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现的目标:当屏幕从ScreenOne切换到ScreenTwo时,运行"while循环"功能,直到按下ScreenTwo上的按钮并打破循环为止.

What I am trying to achieve: when the screen switches from ScreenOne to ScreenTwo, run a 'while loop' function until a button on ScreenTwo is pressed and breaks the loop.

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

This function is supposed to run and receive inputs from a barcode scanner attached to my computer (Meaning, the inputs are the barcodes) and updates the label on ScreenTwo with the number of barcode scanned.

然后,一旦我不再有要扫描的条形码,请按ScreenTwo上的完成"按钮-应该发送输入"999"来中断循环功能.

Then once I have no more barcode to scan, press "Done" button on ScreenTwo - and that is supposed to send input "999" to break the loop function.

我如何尝试在屏幕切换时运行功能:使用"on_enter"

How I tried to run function when screen switches: using 'on_enter'

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

我正面临的问题:

  1. 屏幕从ScreenOne切换到ScreenTwo,并且该功能运行(我看到它在Mac终端上发生)但是无法按下ScreenTwo上的按钮(Mac色轮旋转). /li>
  2. 我还没有弄清楚如何使完成"按钮将输入"999"发送到函数以中断循环.
  1. The screen switches from ScreenOne to ScreenTwo, and the function runs (I see it happening on the Mac terminal) BUT the buttons on ScreenTwo can't be pressed (Mac colour wheel spins).
  2. And I have not figured out how to have the "Done" button send input '999' to the function to break the loop.

我该如何解决1?

我如何达到2分?

分别是ScreenOne和ScreenTwo的屏幕截图:

Here are Screenshots of the ScreenOne and ScreenTwo respectively:

这是returnStation2.py文件

Here's the returnStation2.py file

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

Here is the returnStationLayout2.kv

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

The "Done" button (in ScreenTwo) is at the bottom of the script.

当屏幕切换到ScreenTwo时无法按下. 我希望按下该键时可以输入"999"来中断正在运行的循环功能.

It can't be pressed when the screen is switched to ScreenTwo. And I hope that when pressed, it can input '999' to break the loop function that is running.

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

推荐答案

解决方案

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

Solution

This answer is based on discussion in comments section present under the question. The code below is written under an assumption that the scanner sends a specific signal when a barcode is scanned. The overall idea is to run a function after that signal was sent.

我建议您熟悉kivy的时钟对象.可以创建一个侦听器功能,该功能将检查是否每n秒发送一次信号.准确地说,假设您想在检测到信号后运行process()函数.我们还要声明一个变量scanned来存储是否成功扫描条形码的信息,并创建一个侦听器来检查是否已发送信号(因此请检查scanned变量是否包含True).下面的代码示例将每2秒将scanned变量设置为True以模仿扫描行为.

I suggest getting familiar with kivy's Clock object. It is possible to create a listener function that would check if the signal was sent every n seconds. Precisely, let's say you want to run process() function once a signal was detected. Let's also declare a variable scanned to store information if a barcode was succesfully scanned and create a listener to check if the signal was sent (so check if the scanned variable holds True). Following code sample sets the scanned variable every 2 seconds to True to mimic the scanning behaviour.

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.

这篇关于kivy:如何在屏幕切换不挂屏的情况下运行循环功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆