python / kivy: нужна функция clock (), но cra sh из-за рекурсии - PullRequest
0 голосов
/ 11 июля 2020

Я новичок в python и kivy и пытаюсь учиться на фрагментах кода, методом проб и ошибок. Но теперь я застрял. Для отображения погоды и информации о мусоре на малине я использовал kivy. Чтобы получить эту информацию, я использую функцию URLRequest. Этой функции нужна функция часов

    while not req.is_finished:
    Clock.tick()
    return req.result

Итак, программа работает, отображает информацию, но регулярно вылетает через 20 минут или около того с ошибкой "RuntimeError: превышена максимальная глубина рекурсии. Но я не понимаю, как Я могу избавиться от рекурсии, продолжая работать: (

Вот еще код в контексте. Кто-нибудь может помочь?

    # -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.network.urlrequest import UrlRequest
from time import gmtime, strftime, localtime, sleep

class garbage:
    def garbage_text(garbage):
        req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22ABFALL%22,%22next_text%22,0)}&XHR=1&fwcsrf=password')
        while not req.is_finished:
            Clock.tick()
        return req.result

class weather:
    def weather_db1(weather):
        req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password')
        while not req.is_finished:
            Clock.tick()
        return req.result

class MyBox(BoxLayout):
    def update(self, *args):

        uweather = weather()
        aktw = uweather.weather_db1()

        ggarbage = garbage()
        garbagetext = ggarbage.garbage_text()


        self.ids.temp_ist.text = str(aktw)

        self.ids.uhrzeit_top.text = strftime("%H:%M", localtime())
        self.ids.datum_top.text = strftime("%d.%m.%Y", localtime())

        self.ids.garbage_std.text = garbagetext+" rausstellen "

class ControlApp(App):
    def build(self):
        actclock = MyBox()
        Clock.schedule_interval(actclock.update, 1)
        return actclock

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

1 Ответ

0 голосов
/ 11 июля 2020

Вот измененная версия вашего кода, которая использует обратные вызовы вместо цикла или ожидания:

from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock, mainthread
from kivy.uix.boxlayout import BoxLayout
from kivy.network.urlrequest import UrlRequest
from time import strftime, localtime

class garbage:
    def garbage_text(self, *args):
        req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password',
            on_success=self.update, on_failure=self.failure)

    @mainthread
    def update(self, req, result):
        # update the GUI
        garbage_std = App.get_running_app().root.ids.garbage_std
        garbage_std.text = str(result)+" rausstellen "

        # schedule the next update
        Clock.schedule_once(self.garbage_text, 1)

    def failure(self):
        print('garbage failed')

class weather:
    def weather_db1(self, *args):
        req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password',
            on_success=self.update, on_failure=self.failure)

    @mainthread
    def update(self, req, result):
        # update the GUI
        temp_ist = App.get_running_app().root.ids.temp_ist
        temp_ist.text = str(result)

        # schedule the next update
        Clock.schedule_once(self.weather_db1, 1)

    def failure(self):
        print('weather failed')

class MyBox(BoxLayout):
    def update(self, *args):
        self.ids.uhrzeit_top.text = strftime("%H:%M", localtime())
        self.ids.datum_top.text = strftime("%d.%m.%Y", localtime())

class ControlApp(App):
    def build(self):
        actclock = MyBox()
        self.weather = weather()
        self.garbage = garbage()

        # start the time updates
        Clock.schedule_interval(actclock.update, 1)

        # start the other updates
        Clock.schedule_once(self.weather_update)
        Clock.schedule_once(self.garbage_update)

        return actclock

    def weather_update(self, dt):
        self.weather.weather_db1()

    def garbage_update(self, dt):
        self.garbage.garbage_text()

Builder.load_string('''
<MyBox>:
    orientation: 'vertical'
    Label:
        id: temp_ist
    Label:
        id: uhrzeit_top
    Label:
        id: datum_top
    Label:
        id: garbage_std
''')

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