我如何不断更新我在 kivy 中的标签?

how do i continously keep on updating my label in kivy?

我已经在这个问题上停留了几个小时了。 我正在制作一个自制的 smarthome 终端,并且已经对 kivy 进行了大约 2 周的修补,到目前为止它一直很棒。我现在想在屏幕内的标签内显示温度。我制作了一个带有 4 个按钮的操作栏,单击时可以在屏幕上滑动。在名为 "Thermostaat" 的第一个屏幕中,我想显示一个标签,其中包含从我编写的另一个外部脚本中读取的温度。我似乎无法获得标签内的温度,即使是虚拟值也是如此” 这是我的 main.py:

#!/usr/bin/env python3
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy.lang import Builder

class Menu(BoxLayout):
    manager = ObjectProperty(None)
    def __init__(self,**kwargs):
        super(Menu, self).__init__(**kwargs)
        Clock.schedule_interval(self.getTemp, 1)
    def getTemp(self,dt):
        thetemp = 55 #will be changed to temp.read()
        self.ids.TempLabel.text = str(thetemp)
        print(thetemp)

class ScreenThermo(Screen):
    pass

class ScreenLight(Screen):
    pass

class ScreenEnergy(Screen):
    pass

class ScreenWeather(Screen):
    pass

class Manager(ScreenManager):
    screen_thermo = ObjectProperty(None)
    screen_light = ObjectProperty(None)
    screen_energy = ObjectProperty(None)
    screen_weather = ObjectProperty(None)

class MenuApp(App):
    def thermostaat(self):
        print("Thermostaat")

    def verlichting(self):
        print("Verlichting")

    def energie(self):
        print("Energie")

    def weer(self):
        print("Het Weer")

    def build(self):
        Builder.load_file("test.kv")
        return Menu()


if __name__ == '__main__':
    MenuApp().run()

这是我的 .kv 文件:

#:kivy 1.10.0
<Menu>:

    manager: screen_manager
    orientation: "vertical"
    ActionBar:
        size_hint_y: 0.05
        ActionView:
            ActionPrevious:
            ActionButton:
                text: "Thermostaat"
                on_press: root.manager.current= 'thermo'
                on_release: app.thermostaat()
            ActionButton:
                text: "Verlichting"
                #I want my screens to switch when clicking on this actionbar button
                on_press: root.manager.current= 'light'
                on_release: app.verlichting()
            ActionButton:
                text: "Energieverbruik"
                on_press: root.manager.current= 'energy'
                on_release: app.energie()
            ActionButton:
                text: "Het Weer"
                on_press: root.manager.current= 'weather'
                on_release: app.weer()
    Manager:
        id: screen_manager

<ScreenThermo>:
    Label:
        #this is where i want my label that shows the temperature my sensor reads
        text: "stuff1"
<ScreenLight>:
    Button:
        text: "stuff2"
<ScreenEnergy>:
    Button:
        text: "stuff3"
<ScreenWeather>:
    Button:
        text: "stuff4"

<Manager>:
    id: screen_manager
    screen_thermo: screen_thermo
    screen_light: screen_light
    screen_energy: screen_energy
    screen_weather: screen_weather

    ScreenThermo:
        id: screen_thermo
        name: 'thermo'
        manager: screen_manager
    ScreenLight:
        id: screen_light
        name: 'light'
        manager: screen_manager
    ScreenEnergy:
        id: screen_energy
        name: 'energy'
        manager: screen_manager
    ScreenWeather:
        id: screen_weather
        name: 'weather'
        manager: screen_manager

我经常遇到以下错误:

super(ObservableDict, self).__getattr__(attr))
 AttributeError: 'super' object has no attribute '__getattr__'

如果您想知道,这是我的追溯:

Traceback (most recent call last):
   File "main.py", line 57, in <module>
     MenuApp().run()
   File "/home/default/kivy/kivy/app.py", line 829, in run
     runTouchApp()
   File "/home/default/kivy/kivy/base.py", line 502, in runTouchApp
     EventLoop.window.mainloop()
   File "/home/default/kivy/kivy/core/window/window_pygame.py", line 403, in mainloop
     self._mainloop()
   File "/home/default/kivy/kivy/core/window/window_pygame.py", line 289, in _mainloop
     EventLoop.idle()
   File "/home/default/kivy/kivy/base.py", line 337, in idle
     Clock.tick()
   File "/home/default/kivy/kivy/clock.py", line 581, in tick
     self._process_events()
   File "kivy/_clock.pyx", line 367, in kivy._clock.CyClockBase._process_events
     cpdef _process_events(self):
   File "kivy/_clock.pyx", line 397, in kivy._clock.CyClockBase._process_events
     raise
   File "kivy/_clock.pyx", line 395, in kivy._clock.CyClockBase._process_events
     event.tick(self._last_tick)
   File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
     ret = callback(self._dt)
   File "main.py", line 17, in getTemp
     self.ids.TempLabel.text = str(thetemp)
   File "kivy/properties.pyx", line 839, in kivy.properties.ObservableDict.__getattr__
     super(ObservableDict, self).__getattr__(attr))
 AttributeError: 'super' object has no attribute '__getattr__'

我希望有人愿意帮助我,因为我想继续这个项目,我的 SmartHome 设备的大部分功能已经可以使用了,所以最后一部分是制作一个像样的 GUI将其全部放入(控制灯光、控制室内温度等...)

使用字符串属性

<ScreenThermo>:
    Label:
        #this is where i want my label that shows the temperature my sensor reads
        text: root.thermo_text


class ScreenThermo(BoxLayout):
      thermo_text = StringProperty("stuff")

...

然后任何时候你想设置文本就可以了

my_screen.thermo_text = "ASD"

您的菜单中没有 id TempLabel

首先,您必须在您的 kv 中添加 TempLabel:

...
<ScreenThermo>:
    Label:
        id: TempLabel
        text: "stuff1"
...

然后更新右边的标签:

...
class Menu(BoxLayout):
    manager = ObjectProperty(None)
    def __init__(self,**kwargs):
        super(Menu, self).__init__(**kwargs)
        Clock.schedule_interval(self.getTemp, 1)
    def getTemp(self,dt):
        thetemp = 55 #will be changed to temp.read()
        self.manager.screen_thermo.ids.TempLabel.text = str(thetemp)
        print(thetemp)
...

使用对象属性

在示例中,我使用 ObjectProperty 连接到温度标签,因为 id 是小部件的弱引用。使用 ObjectProperty 创建直接引用,提供更快的访问并且更明确。

main.py

1。导入外部脚本

from temperature import read_temperature

2。声明对象属性

class ScreenThermo(Screen):
    temperature = ObjectProperty(None)

3。更新温度文本

def getTemp(self, dt):
    temp = read_temperature()
    print(temp)
    self.manager.screen_thermo.temperature.text = str(temp)

menu.kv - kv 文件

4。将 ObjectProperty 连接到 id

<ScreenThermo>:
    temperature: temperature
    Label:
        id: temperature
        #this is where i want my label that shows the temperature my sensor reads
        text: "stuff1"

temperature.py - 模拟器

这是模拟温度的外部脚本。

import random


def read_temperature():
    return random.randint(0, 100)

输出