Reputation: 335
I understand that it is relatively easy to switch screens in the .kv file using on_release. I want to keep my button creating in the .py file, however, so I do not want to use this method. I have done the following to add a function that occurs when the 14th button is pressed. When the button is pressed in the program nothing happens. Experimenting with other names for the screen to sm.current to threw the error: "kivy.uix.screenmanager.ScreenManagerException: No Screen with name "InputScreen" when the 14th button was pressed."
# Kivy Formatting
kv_text='''\
<MyScreenManager>:
LandingScreen:
InputScreen:
<InputScreen@Screen>:
name: 'input_sc'
AnchorLayout:
id: anchor_1
<LandingScreen@Screen>:
name: 'landing_sc'
GridLayout:
id: grid_1
cols: 5
height: 480
width: 800
spacing: 25, 20
padding: 25,25
'''
# Screen Manager
class MyScreenManager(ScreenManager):
pass
# Main screen with button layout
class LandingScreen(Screen):
def __init__(self, **kwargs):
super(LandingScreen, self).__init__(**kwargs)
self.buttons = [] # add references to all buttons here
Clock.schedule_once(self._finish_init)
# IDs have to be used here because they cannot be applied until widget initialized
def _finish_init(self, dt):
self.ids.grid_1.cols = 5
# Loop to make 15 different buttons on screen
for x in range(15):
self.buttons.append(Button(text='button {}'.format(x)))
self.ids.grid_1.add_widget(self.buttons[x])
self.buttons[x].background_normal = 'YOUTUBE.png'
def SwitchScreen(self,*args):
sm.current = 'input_sc'
sm = ScreenManager()
sm.add_widget(InputScreen(name='input_sc'))
sm.add_widget(LandingScreen(name='landing'))
self.buttons[14].bind(on_release=SwitchScreen)
# Input screen
class InputScreen(Screen):
pass
class MySubApp(App):
def build(self):
return MyScreenManager()
def main():
Builder.load_string(kv_text)
app = MySubApp()
app.run()
if __name__ == '__main__':
main()
If someone could help me understand the hole in my current logic I would appreciate it greatly. Thanks.
Upvotes: 1
Views: 1579
Reputation: 4513
Each screen has a manager
property that gives you the instance of the ScreenManager
used. You only need to use it to refer to the ScreemManager
instance and use its current
method:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.clock import Clock
# Kivy Formatting
kv_text='''\
<MyScreenManager>:
LandingScreen:
InputScreen:
<InputScreen@Screen>:
name: 'input_sc'
AnchorLayout:
id: anchor_1
Button:
text: 'Hello'
<LandingScreen@Screen>:
name: 'landing_sc'
GridLayout:
id: grid_1
cols: 5
height: 480
width: 800
spacing: 25, 20
padding: 25,25
'''
# Screen Manager
class MyScreenManager(ScreenManager):
pass
# Main screen with button layout
class LandingScreen(Screen):
def __init__(self, **kwargs):
super(LandingScreen, self).__init__(**kwargs)
self.buttons = [] # add references to all buttons here
Clock.schedule_once(self._finish_init)
# IDs have to be used here because they cannot be applied until widget initialized
def _finish_init(self, dt):
self.ids.grid_1.cols = 5
# Loop to make 15 different buttons on screen
for x in range(15):
self.buttons.append(Button(text='button {}'.format(x)))
self.ids.grid_1.add_widget(self.buttons[x])
self.buttons[x].background_normal = 'YOUTUBE.png'
self.buttons[14].bind(on_release=self.switch_screen)
def switch_screen(self, *args):
self.manager.current = 'input_sc'
# Input screen
class InputScreen(Screen):
pass
class MySubApp(App):
def build(self):
return MyScreenManager()
def main():
Builder.load_string(kv_text)
app = MySubApp()
app.run()
if __name__ == '__main__':
main()
Upvotes: 3