[英]Kivy ScreenManager switching “Start” screen on a condition
I am new to kivy and wanted to start a little app project.我是 kivy 的新手,想开始一个小应用程序项目。 What I want to achieve:
我想要达到的目标:
So far I've found a working solution, but it's not really pleasing me regarding the way it works.到目前为止,我已经找到了一个可行的解决方案,但它的工作方式并没有让我真正满意。 What I want is to create ScreenManager and Screens in the.kv file and have the.py file do the logic (which screen to load by checking if userdata exists in the store).
我想要的是在 .kv 文件中创建 ScreenManager 和 Screens 并让 .py 文件执行逻辑(通过检查存储中是否存在用户数据来加载哪个屏幕)。
I've tried:我试过了:
<WindowManager>:
root.check_for_user()
MainWindow:
UserDataWindow:
<MainWindow>:
...
Here's my working code so far:到目前为止,这是我的工作代码:
main.py:主要.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.storage.jsonstore import JsonStore
class LoginWindow(Screen):
nick = ObjectProperty(None)
isle = ObjectProperty(None)
hemisphere_n = ObjectProperty(None)
hemisphere_s = ObjectProperty(None)
def submit(self):
store = JsonStore('store.json')
if self.hemisphere_n.state == 'down' and self.hemisphere_s.state == 'normal':
store.put('user', nickname=self.nick.text, island=self.isle.text, hemisphere="north")
elif self.hemisphere_n.state == "normal" and self.hemisphere_s.state == "down":
store.put('user', nickname=self.nick.text, island=self.isle.text, hemisphere="south")
class MainWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("my.kv")
sm = WindowManager()
store = JsonStore('store.json')
screens = [MainWindow(name="main"), LoginWindow(name="login")]
for screen in screens:
sm.add_widget(screen)
if store.exists('user'):
print("exists")
sm.current = "main"
else:
print("not found")
sm.current = "login"
class MainApp(App):
def build(self):
return sm
if __name__ == '__main__':
MainApp().run()
my.kv:我的.kv:
#:kivy 1.11.1
<MainWindow>:
FloatLayout:
Label:
text:
Button:
text: "Go Back"
pos_hint: {"x": 0.45, "top": 0.5}
size_hint: (0.1, 0.05)
on_release:
app.root.current = "login"
<LoginWindow>:
nick: nickname
isle: island
hemisphere_n: hemisphere_n
hemisphere_s: hemisphere_s
FloatLayout:
Label:
text: "Nickname:"
pos_hint: {"x": 0.45, "top": 0.7}
size_hint: (0.1, 0.05)
TextInput:
id: nickname
multiline: False
pos_hint: {"x": 0.4, "top": 0.65}
size_hint: (0.2, 0.05)
Label:
text: "Island Name:"
pos_hint: {"x": 0.45, "top": 0.6}
size_hint: (0.1, 0.05)
TextInput:
id: island
multiline: False
pos_hint: {"x": 0.4, "top": 0.55}
size_hint: (0.2, 0.05)
Label:
text: "Hemisphere:"
pos_hint: {"x": 0.45, "top": 0.5}
size_hint: (0.1, 0.05)
ToggleButton:
id: hemisphere_n
text: "North"
group: "hemisphere"
state: "down"
pos_hint: {"x": 0.41, "top": 0.45}
size_hint: (0.08, 0.05)
ToggleButton:
id: hemisphere_s
text: "South"
group: "hemisphere"
pos_hint: {"x": 0.51, "top": 0.45}
size_hint: (0.08, 0.05)
Button:
text: "Submit"
pos_hint: {"x": 0.45, "top": 0.38}
size_hint: (0.1, 0.05)
on_press:
root.submit()
on_release:
app.root.current = "main"
Please ignore the loose ends at some points.请忽略某些方面的松散端。 I wanted to get this working before going any further.
在继续之前,我想先完成这项工作。 It now goes to the main screen (when I add the screens to screenmanager), then checks for user data and eventually switches to login.
它现在进入主屏幕(当我将屏幕添加到屏幕管理器时),然后检查用户数据并最终切换到登录。 Do you have any suggestions?
你有什么建议吗? Thanks in advance.
提前致谢。
You can put your Screen
choice logic pretty much anywhere you want it.您几乎可以将
Screen
选择逻辑放在您想要的任何地方。 Here is an example of putting it in your WindowManager
class:这是将其放入
WindowManager
class 的示例:
class WindowManager(ScreenManager):
def select_start_screen(self):
store = JsonStore('store.json')
self.transition = NoTransition()
if store.exists('user'):
print("exists")
self.current = "main"
else:
print("not found")
self.current = "login"
self.transition = SlideTransition()
Then you can call the select_start_screen()
in your build()
method:然后你可以在你的
build()
方法中调用select_start_screen()
:
class MainApp(App):
def build(self):
sm.select_start_screen()
return sm
What you are seeing is the transition
animation.您看到的是
transition
animation。 You can eliminate that by using NoTransition()
like this:您可以像这样使用
NoTransition()
来消除这种情况:
sm.transition = NoTransition()
if store.exists('user'):
print("exists")
sm.current = "main"
else:
print("not found")
sm.current = "login"
sm.transition = SlideTransition()
How about adding a blank screen first in addtion to @John's answer.除了@John 的答案之外,如何先添加一个空白屏幕。
sm.add_widget(Screen(name='blank'))
for screen in screens:
sm.add_widget(screen)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.