Goal is to move to a settings screen when no button is pressed, text is entered or whatever for a certain time.
In fact, functionality is like a screensaver of some sorts.
code version 1
import signal
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class wiscApp(App):
def setscreensaver(self, *args):
print("switching to settings")
# --> here I need to switch to the settings screen
# but this doens't work, bnoth sm and setscreen are not known here
sm.switch_to(setscreen)
def resetscreensavertimeout(self):
print("resetting screensaver timer")
signal.alarm(10) # just 5 seconds for debugging
def build(self):
sm = ScreenManager()
setscreen = SettingsScreen(name='settings')
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(setscreen)
signal.signal(signal.SIGALRM, self.setscreensaver)
self.resetscreensavertimeout()
return sm
if __name__ == "__main__":
wiscApp().run()
and the .kv
<MenuScreen>:
BoxLayout:
orientation: 'vertical'
BoxLayout:
Button:
text: "resettimeout"
on_press: app.resetscreensavertimeout()
Button:
text: "do other things"
Button:
text: 'settings'
on_press: root.manager.current = 'settings'
<SettingsScreen>:
BoxLayout:
Button:
text: "stop app"
on_press: app.stop()
Button:
text: 'Back to menu'
on_press: root.manager.current = 'menu'
This works perfectly up until the calling of sm.switch_to(setscreen)
in the setscreensaver function.
I tried the following: code version 2
import signal
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class wiscApp(App):
sm = ScreenManager()
setscreen = SettingsScreen(name='settings')
def setscreensaver(self, *args):
print("switching to settings")
# --> here I need to switch to the settings screen
# but this doens't work, bnoth sm and setscreen are not known here
self.sm.switch_to(self.setscreen)
def resetscreensavertimeout(self):
print("resetting screensaver timer")
signal.alarm(10) # just 5 seconds for debugging
def build(self):
self.sm.add_widget(MenuScreen(name='menu'))
self.sm.add_widget(self.setscreen)
signal.signal(signal.SIGALRM, self.setscreensaver)
self.resetscreensavertimeout()
return self.sm
if __name__ == "__main__":
wiscApp().run()
But then the settings screen is BLANK! In the first version of the code, I understand by it doens't work: both sm and setscreen are undefined variables in that function. In the second version, I don't understand why the settings screen is blank.
edit *** version 3 of the code***
import signal
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class wiscApp(App):
def setscreensaver(self, *args):
print("switching to settings")
# --> here I need to switch to the settings screen
# but this doens't work, bnoth sm and setscreen are not known here
self.sm.switch_to(self.setscreen)
def resetscreensavertimeout(self):
print("resetting screensaver timer")
signal.alarm(10) # just 5 seconds for debugging
def build(self):
self.sm = ScreenManager()
self.setscreen = SettingsScreen(name='settings')
self.sm.add_widget(MenuScreen(name='menu'))
self.sm.add_widget(self.setscreen)
signal.signal(signal.SIGALRM, self.setscreensaver)
self.resetscreensavertimeout()
return self.sm
if __name__ == "__main__":
wiscApp().run()
In this version 3, transitioning to the settings screen with the signal works fine, but if I then click the menu button, I get this error (this error does not appear in the other versions of the code):
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "menu".
So, I have several questions
thanks a lot!
Here is a modified version of your code that uses Clock.schedule_once()
instead of signal
:
class wiscApp(App):
def setscreensaver(self, *args):
print("switching to settings")
self.resetscreensavertimeout()
self.sm.current = 'settings'
def resetscreensavertimeout(self, *args):
print("resetting screensaver timer")
self.resetEvent.cancel()
self.resetEvent = Clock.schedule_once(self.setscreensaver, 5)
def build(self):
self.sm = ScreenManager()
self.setscreen = SettingsScreen(name='settings')
self.sm.add_widget(MenuScreen(name='menu'))
self.sm.add_widget(self.setscreen)
self.resetEvent = Clock.schedule_once(self.setscreensaver, 5)
Window.bind(on_touch_down=self.resetscreensavertimeout)
Window.bind(on_key_down=self.resetscreensavertimeout)
return self.sm
This also uses Window.bind()
to trigger the reset of the timeout whenever a button is pressed or a key is pressed.