kivy: как запустить функцию петли, когда экран переключается без зависания экрана? - PullRequest
0 голосов
/ 23 мая 2018

Чего я пытаюсь достичь: когда экран переключается с ScreenOne на ScreenTwo, запускайте функцию while, пока кнопка на ScreenTwo не будет нажата и не прервет цикл.

Эта функция должна запускаться и получать входные данные от сканера штрих-кода, подключенного к моему компьютеру (имеется в виду, что входные данные являются штрих-кодами), и обновляет метку на ScreenTwo количеством сканированных штрих-кодов.

Затем, когда у меня больше нет штрих-кода для сканирования, нажмите кнопку «Готово» на ScreenTwo - и это должно отправить вход «999», чтобы разорвать функцию цикла.

КакЯ пытался запустить функцию, когда экран переключается: с помощью 'on_enter'

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

Проблема, с которой я сталкиваюсь:

  1. Экран переключается с ScreenOneна ScreenTwo, и функция запускается (я вижу, что это происходит на терминале Mac) НО кнопки на ScreenTwo не могут быть нажаты (вращается колесо цвета Mac).
  2. И у меня нетвыяснили, как заставить кнопку «Готово» отправить на вход «999» функцию разрыва цикла.

Как мне разрешить 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 голосов
/ 23 мая 2018

Решение

Этот ответ основан на обсуждении в разделе комментариев под вопросом.Приведенный ниже код написан в предположении, что сканер отправляет определенный сигнал при сканировании штрих-кода.Общая идея состоит в том, чтобы запустить функцию после того, как этот сигнал был отправлен.

Тактовый цикл

Я предлагаю ознакомиться с объектом Clock Киви.Можно создать функцию слушателя, которая будет проверять, был ли сигнал отправлен каждые n секунд.Точно, скажем, вы хотите запустить функцию process() после обнаружения сигнала.Давайте также объявим переменную scanned для хранения информации, если штрих-код был успешно отсканирован, и создадим прослушиватель, чтобы проверить, был ли отправлен сигнал (поэтому проверьте, содержит ли переменная scanned True).Следующий пример кода устанавливает переменную scanned каждые 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...