I've been trying to build my kv language skills from Accessing id/widget of different class from a kivy file (.kv) using Kivy's clock? by working with the information found in Kivy Screen manager reference in kv language. Unfortunately the latter post does not contain a complete working code example so I can't understand how to make changes to the text elements in a on a specific screen in a multi-screen Kivy application.
After searching much of the day I can't find any simple concrete working examples of how to build a multi-screen app in kv language so here I am. I don't seem to be able to set up the proper references to the individual screens so I can change them.
In the simple example code below I have built a four screen application that switches automatically between four screens. There are 2 things I'd like to learn from this question;
The kv language code that would set-up as much of the screenmanager as possible. ie. can lines 43 thru 47 be reduced or eliminated by the kv language?
The actual python code (which I believe would go on line 56 of the app) that changes the text on the first screen to "Hi I'm The Fifth Screen" prior to it displayed the second time.
Code below. Thanks in advance. ....brad....
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<FirstScreen>:
name: '_first_screen_'
Label:
id: first_screen
text: "Hi I'm The First Screen"
<SecondScreen>:
name: '_second_screen_'
Label:
id: second_screen
text: "Hi I'm The Second Screen"
<ThirdScreen>:
name: '_third_screen_'
Label:
id: third_screen
text: "Hi I'm The Third Screen"
<FourthScreen>:
name: '_fourth_screen_'
Label:
id: fourth_screen
text: "Hi I'm The Fourth Screen"
""")
class FirstScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ThirdScreen(Screen):
pass
class FourthScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(FirstScreen())
sm.add_widget(SecondScreen())
sm.add_widget(ThirdScreen())
sm.add_widget(FourthScreen())
class SwitchingScreenApp(App):
def build(self):
Clock.schedule_once(self.screen_switch_one, 2)
Clock.schedule_once(self.screen_switch_two, 4)
Clock.schedule_once(self.screen_switch_three, 6)
Clock.schedule_once(self.screen_switch_four, 8)
# Want to place the code here that changes the first_screen text to "Hi I'm The Fifth Screen"
Clock.schedule_once(self.screen_switch_one, 10)
return sm
def screen_switch_one(a,b):
sm.current = '_first_screen_'
def screen_switch_two(a,b):
sm.current = '_second_screen_'
def screen_switch_three(a,b):
sm.current = '_third_screen_'
def screen_switch_four(a,b):
sm.current = '_fourth_screen_'
SwitchingScreenApp().run()
Firstly, I would suggest splitting your codes into Python and kv file, because as your program grows, it will be easier to maintain the UIs/widgets and the Python code. Please refer to the example (app_with_kv.py, switchingscreen.kv, output) for details.
The kv language code that would set-up as much of the screenmanager as possible. ie. can lines 43 thru 47 be reduced or eliminated by the kv language?
sm = ScreenManager()
sm.add_widget(FirstScreen())
sm.add_widget(SecondScreen())
sm.add_widget(ThirdScreen())
sm.add_widget(FourthScreen())
Add a class MyScreenManager into your Python code.
class MyScreenManager(ScreenManager):
pass
...
def build(self):
sm = MyScreenManager()
Addd the following kv rule either inline or in a separate kv file. This is equivalent to using the statement, sm.add_widget() four times.
<MyScreenManager>:
FirstScreen:
SecondScreen:
ThirdScreen:
FourthScreen:
The actual python code (which I believe would go on line 56 of the app) that changes the text on the first screen to "Hi I'm The Fifth Screen" prior to it displayed the second time.
You have to place the following code in any of the 3 switching screen methods excluding the first switching screen method, screen_switch_one()
self.ids.first_screen.ids.first_screen_label.text = "Hi I'm The Fifth Screen"
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
class FirstScreen(Screen):
pass
class SecondScreen(Screen):
pass
class ThirdScreen(Screen):
pass
class FourthScreen(Screen):
pass
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
Clock.schedule_once(self.screen_switch_one, 2)
def screen_switch_one(self, dt):
self.current = '_first_screen_'
Clock.schedule_once(self.screen_switch_two, 2)
def screen_switch_two(self, dt):
self.current = '_second_screen_'
self.ids.first_screen.ids.first_screen_label.text = "Hi I'm The Fifth Screen"
Clock.schedule_once(self.screen_switch_three, 2)
def screen_switch_three(self, dt):
self.current = '_third_screen_'
Clock.schedule_once(self.screen_switch_four, 2)
def screen_switch_four(self, dt):
self.current = '_fourth_screen_'
Clock.schedule_once(self.screen_switch_one, 2)
class SwitchingScreenApp(App):
def build(self):
return MyScreenManager()
if __name__ == "__main__":
SwitchingScreenApp().run()
#:kivy 1.10.0
<MyScreenManager>:
FirstScreen:
id: first_screen
SecondScreen:
ThirdScreen:
FourthScreen:
<FirstScreen>:
name: '_first_screen_'
Label:
id: first_screen_label
text: "Hi I'm The First Screen"
<SecondScreen>:
name: '_second_screen_'
Label:
id: second_screen_label
text: "Hi I'm The Second Screen"
<ThirdScreen>:
name: '_third_screen_'
Label:
id: third_screen_label
text: "Hi I'm The Third Screen"
<FourthScreen>:
name: '_fourth_screen_'
Label:
id: fourth_screen_label
text: "Hi I'm The Fourth Screen"