I am trying to have a function run continuously and spit out a distance that the label uses that I'll eventually tie to a sonar module, but the label remains blank and I am at a loss as to what I am doing wrong. If I just add a print statement for that distance variable it prints and updates just fine, just can't get the label to use it.
Part II of my question is how do I reference my same function in the second window and also have a label that updates from that same function?
Thanks for the help in advance, I am very very new to kivy and just started learning python a few months ago as well.
Python code:
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"
To simplify the access to distance
, you can put that StringProperty
in the 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()
Note that I have also moved the Builder.load_file()
inside the App
. This is good practice when you reference app
in the kv
file (as I have done). Also, calling the sonar()
method using MySonar.sonar(self)
will not work. You need to use a reference to the instance of MySonar
that is in your GUI.
Now the kv
file becomes:
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"
The change is that the text
attribute of both Labels
is now just app.distance
.