目标是在一段时间内未按下任何按钮、输入文本或其他任何内容时移动到设置屏幕。
事实上,功能就像某种屏幕保护程序。
代码版本 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()
和 .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'
直到在 setscreensaver 函数中调用 sm.switch_to(setscreen)
之前,这都能正常工作。
我尝试了以下方法: 代码版本 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()
但是设置屏幕是空白的! 在代码的第一个版本中,我理解它不起作用:sm 和 setscreen 都是该函数中的未定义变量。 在第二个版本中,我不明白为什么设置屏幕是空白的。
编辑 *** 代码的第 3 版***
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()
在这个版本 3 中,转换到带有信号的设置屏幕工作正常,但是如果我然后单击菜单按钮,我会收到此错误(此错误不会出现在其他版本的代码中):
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "menu".
所以,我有几个问题
非常感谢!
答案 0 :(得分:0)
这是您的代码的修改版本,它使用 Clock.schedule_once()
而不是 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
这也使用 Window.bind()
在按下按钮或按键时触发超时重置。