Как динамически обновлять метку Kivy из непрерывно работающей функции?

#python #dynamic #kivy #label #window

#python #динамический #kivy #метка #окно

Вопрос:

Я пытаюсь заставить функцию работать непрерывно и указать расстояние, которое использует метка, которое я в конечном итоге свяжу с модулем sonar, но метка остается пустой, и я не понимаю, что я делаю неправильно. Если я просто добавлю оператор печати для этой переменной расстояния, он печатает и обновляется просто отлично, просто не может заставить метку использовать его.

Часть II моего вопроса заключается в том, как мне ссылаться на мою ту же функцию во втором окне, а также иметь метку, которая обновляется из той же функции?

Заранее спасибо за помощь, я очень новичок в kivy и только начал изучать python несколько месяцев назад.

Код Python:

 from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen  # for multiple screens
from kivy.properties import StringProperty


class MySonar(Screen):
    global i
    i = 1

    distance = StringProperty("")

    #Generic function that just adds itself up, just using to try and get the label to change before I throw in my real function
    def sonar(self):
        global i

        if i < 250:
            distance = (10   .1 * i)
            i  = 1

        else:
            i = 1
            distance = 10

        self.root.distance=str(distance)

class DropWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

kv = Builder.load_file("help.kv")

class HelpMe(App):
    def build(self):

        #running interval update to keep running code above
        Clock.schedule_interval(lambda dt: MySonar.sonar(self), 0.1)

        return kv

if __name__ == "__main__":
    HelpMe().run()
  

Kivy:

 WindowManager:
    MySonar:
    DropWindow:

<MySonar>:
    name:"Main"

    GridLayout:
        cols:1

        ##Need this to update
        Label:
            text:root.distance
        Button:
            text:"Next Window"
            on_release:
                app.root.current="Drop"
                root.manager.transition.direction="left"


<DropWindow>:
    name:"Drop"

    GridLayout:

        cols:1

        ##Need this to update, commented out the text so the program will run and you can see the blank label for part one of my question
        Label:
            ##text:root.distance

        Button:
            text:"Cancel"
            on_release:
                app.root.current="Main"
                root.manager.transition.direction="right"
  

Ответ №1:

Чтобы упростить доступ к distance , вы можете поместить это StringProperty в HelpMe App :

 class MySonar(Screen):
    global i
    i = 1

    #Generic function that just adds itself up, just using to try and get the label to change before I throw in my real function
    def sonar(self):
        global i

        if i < 250:
            distance = (10   .1 * i)
            i  = 1

        else:
            i = 1
            distance = 10

        # set the value of distance in the StringProperty of the App
        App.get_running_app().distance=str(distance)
        print(distance)

class DropWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

# kv = Builder.load_file("help.kv")


class HelpMe(App):
    distance = StringProperty('')

    def build(self):
        kv = Builder.load_file("help.kv")

        #running interval update to keep running code above
        sonar_instance = kv.get_screen('Main')
        Clock.schedule_interval(lambda dt: sonar_instance.sonar(), 0.1)

        return kv

if __name__ == "__main__":
    HelpMe().run()
  

Обратите внимание, что я также переместил Builder.load_file() внутреннюю App часть . Это хорошая практика, когда вы ссылаетесь app на kv файл (как я сделал). Кроме того, вызов sonar() метода using MySonar.sonar(self) не будет работать. Вам нужно использовать ссылку на экземпляр MySonar , который находится в вашем графическом интерфейсе.

Теперь kv файл становится:

 WindowManager:
    MySonar:
    DropWindow:

<MySonar>:
    name:"Main"

    GridLayout:
        cols:1

        ##Need this to update
        Label:
            text: app.distance
        Button:
            text:"Next Window"
            on_release:
                app.root.current="Drop"
                root.manager.transition.direction="left"


<DropWindow>:
    name:"Drop"

    GridLayout:

        cols:1

        ##Need this to update, commented out the text so the program will run and you can see the blank label for part one of my question
        Label:
            text: app.distance

        Button:
            text:"Cancel"
            on_release:
                app.root.current="Main"
                root.manager.transition.direction="right"
  

Изменение заключается в том, что text атрибут обоих Labels теперь просто app.distance .