Kivy: changing screen from python code
Solution 1
Here is a simple 'game' example based on your additional info. When a player enters the game screen, their health points are bleeding. When the pool reaches zero, they are sent back to menu screen.
main.py:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty, NumericProperty
import time
import threading
class ScreenOne(Screen):
pass
class ScreenTwo(Screen):
health_points = NumericProperty(100)
def __init__(self, **kwargs):
super(ScreenTwo, self).__init__(**kwargs)
def on_health_points(self, instance, value):
if value < 1:
self.changeScreen()
def on_enter(self, *args):
thread = threading.Thread(target=self.bleed)
thread.daemon = True
thread.start()
def bleed(self, *args):
while self.health_points > 0:
self.health_points -= 5
time.sleep(0.1)
def displayScreenThenLeave(self):
self.changeScreen()
def changeScreen(self):
if self.manager.current == 'screen1':
self.manager.current = 'screen2'
else:
self.manager.current = 'screen1'
class Manager(ScreenManager):
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
class ScreensApp(App):
def build(self):
m = Manager(transition=NoTransition())
return m
if __name__ == "__main__":
ScreensApp().run()
screens.kv:
#:kivy 1.8.0
<ScreenOne>:
BoxLayout:
orientation: "vertical"
size: root.size
spacing: 20
padding: 20
Label:
text: "Main Menu"
Button:
text: "Button 1"
on_release:
root.manager.current = "screen2"
# reset health_points
root.manager.ids.screen_two.health_points = 100
<ScreenTwo>:
BoxLayout:
orientation: "vertical"
size: root.size
spacing: 20
padding: 20
Label:
id: label
text: "health points: " + str(root.health_points)
<Manager>:
id: screen_manager
screen_one: screen_one
screen_two: screen_two
ScreenOne:
id: screen_one
name: "screen1"
manager: screen_manager
ScreenTwo:
id: screen_two
name: "screen2"
manager: screen_manager
Solution 2
Make these little changes
#import Clock to create a schedule
from kivy.clock import Clock
class ScreenTwo(Screen):
def __init__(self,**kwargs):
super(ScreenTwo, self).__init__(**kwargs)
#this is event that is fired when the screen is displayed.
def on_enter(self, *args):
self.displayScreenThenLeave()
def displayScreenThenLeave(self):
#schedued after 3 seconds
Clock.schedule_once(self.changeScreen, 3)
def changeScreen(self, *args):
#now switch to the screen 1
self.parent.current = "screen1"
for more imformation go to these links Screen Manager, Clock
R. Duke
Updated on June 28, 2022Comments
-
R. Duke almost 2 years
I'm putting together a Kivy app and am having some problems working out how to change screens at an arbitrarily chosen point within the python code.
In the following example, I would like to know how to switch from
Screen2
back toScreen1
by executing a function mymain.py
file.Here's my
main.py
:# -*- coding: utf-8 -*- from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition from kivy.properties import ObjectProperty from functools import partial import random import time class ScreenOne(Screen): pass class ScreenTwo(Screen): def __init__(self,**kwargs): super(ScreenTwo, self).__init__(**kwargs) self.displayScreenThenLeave() def displayScreenThenLeave(self): # 'time.sleep(3)' is a stand-in for "execute some code here" time.sleep(3) self.changeScreen() # I want this function to send the user back to ScreenOne. def changeScreen(self): pass class Manager(ScreenManager): screen_one = ObjectProperty(None) screen_two = ObjectProperty(None) class ScreensApp(App): def build(self): m = Manager(transition=NoTransition()) return m if __name__ == "__main__": ScreensApp().run()
And here's my
screens.kv
:#:kivy 1.8.0 <ScreenOne>: BoxLayout: orientation: "vertical" size: root.size spacing: 20 padding: 20 Label: text: "Main Menu" Button: text: "Button 1" on_release: root.manager.current = "screen2" <ScreenTwo>: BoxLayout: orientation: "vertical" size: root.size spacing: 20 padding: 20 Label: id: label text: "Welcome to Screen 2, please wait three seconds" <Manager>: id: screen_manager screen_one: screen_one screen_two: screen_two ScreenOne: id: screen_one name: "screen1" manager: screen_manager ScreenTwo: id: screen_two name: "screen2" manager: screen_manager
As should be pretty evident, I'm a total beginner at Kivy, so I'd really appreciate it if you could show me exactly what I need to change, including the specific syntax that should be used.
Thanks in advance for your time and wisdom.
-
R. Duke over 8 yearsThanks very much @kiok46 that's a great answer. Unfortunately, I still haven't been able to fix my problem. Appologies for not wording my question better. What I really need to know is how to change screen at an arbitrarily choosen point in the execution of the python code, not how to load a screen and then automatically leave it again it after waiting of for a certain number of seconds (though that is cool to know). The
time.sleep(3)
line was just meant as a stand in for#execute random code here
. Sorry for not being clearer. Any chance you could help me out a bit more? -
jligeza over 8 years@R.Duke Could you write what exactly are you trying to do, without unnecessary abstraction? What is screen one, and what is screen two? In which case do you need to change screen to #1, and when to screen #2?
-
R. Duke over 8 years@zmarszczony Screen One is a menu screen, that at present just contains a single button sending you to Screen Two. Screen Two is a game screen. For the sake of giving a simple example, the "game" in Screen Two just consists of waiting for three seconds, but it could be any sort of game. What I need to know how to do is how to send the user from Screen Two back to Screen One when certain conditions are met, e.g. when their health equals zero.
-
R. Duke over 8 yearsAwesome. Thanks very much.
-
Vishal Kumar Sahu over 3 years
self.parent.current = "your_screen_name"