我已经被困在这个上好几个小时了。 我正在制作一个自制的智能家居终端,并且已经对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适应所有(控制灯,控制房子里的温度等...)
答案 0 :(得分:2)
使用StringProperty
<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"
答案 1 :(得分:2)
菜单中没有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)
...
答案 2 :(得分:1)
在示例中,我使用ObjectProperty来连接温度标签,因为id是小部件的弱参数。使用 ObjectProperty 可创建直接引用,提供更快的访问速度,并且更加明确。
from temperature import read_temperature
class ScreenThermo(Screen):
temperature = ObjectProperty(None)
def getTemp(self, dt):
temp = read_temperature()
print(temp)
self.manager.screen_thermo.temperature.text = str(temp)
<ScreenThermo>:
temperature: temperature
Label:
id: temperature
#this is where i want my label that shows the temperature my sensor reads
text: "stuff1"
这是一个模拟温度的外部脚本。
import random
def read_temperature():
return random.randint(0, 100)