kivy:如何在屏幕切换不挂屏的情况下运行循环功能? [英] kivy: how to run loop function when screen switches without hanging screen?
问题描述
我要实现的目标:当屏幕从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()
我正面临的问题:
- 屏幕从ScreenOne切换到ScreenTwo,并且该功能运行(我看到它在Mac终端上发生)但是无法按下ScreenTwo上的按钮(Mac色轮旋转). /li>
- 我还没有弄清楚如何使完成"按钮将输入"999"发送到函数以中断循环.
- 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).
- 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屋!