python - Kivy ScreenManager 在条件下切换“开始”屏幕
问题描述
我是 kivy 的新手,想开始一个小应用程序项目。我想要达到的目标:
- 当您第一次启动应用程序时 -> 显示带有某种用户数据表单的屏幕
- 将数据存储在 JsonStore -> 转到主屏幕
- 下次运行应用程序 -> 检查用户数据是否在 JsonStore 中并直接进入主屏幕
到目前为止,我已经找到了一个可行的解决方案,但它的工作方式并没有让我真正满意。我想要的是在 .kv 文件中创建 ScreenManager 和 Screens 并让 .py 文件执行逻辑(通过检查存储中是否存在用户数据来加载哪个屏幕)。
我试过了:
- 使用 ScreenManager 类 (def __init__) - 没有成功
- 从 .kv 文件中调用方法,如下所示(也不起作用):
<WindowManager>:
root.check_for_user()
MainWindow:
UserDataWindow:
<MainWindow>:
...
到目前为止,这是我的工作代码:
主要.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()
我的.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"
请忽略某些方面的松散端。在继续之前,我想先完成这项工作。它现在进入主屏幕(当我将屏幕添加到屏幕管理器时),然后检查用户数据并最终切换到登录。你有什么建议吗?提前致谢。
解决方案
您Screen
几乎可以将您的选择逻辑放在您想要的任何地方。这是将其放入您的WindowManager
班级的示例:
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()
然后你可以select_start_screen()
在你的build()
方法中调用:
class MainApp(App):
def build(self):
sm.select_start_screen()
return sm
推荐阅读
- javascript - 在 mongodb 中使用 $inc 和 $addToSet
- python - 如何解决 pymysql.err.ProgrammingError: 1064 - 在 mysql 上保存数据?
- c# - 在 Excel 功能区上,如何将按钮一直向右对齐?
- javascript - 使用 Google API 自动完成电子邮件地址
- oracle-apex - 访问通过 APEX_ITEM.SELECT_LIST 创建的页面上的项目
- django - 如何在 Django 列表中添加序列号?
- c# - UWP 应用程序的 Azure 服务总线
- spring - 使用 Spring 和 Hibernate 4.3.5 无法正确打印 JSON
- python - 为什么 eval 尝试在 __builtins__ 上下标?
- php - empty() 在 PHP 中使用 isset() 吗?