简体   繁体   English

Kivy ScreenManager 在条件下切换“开始”屏幕

[英]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:我想要达到的目标:

  • when you start the app for the first time -> show a screen with some kind of userdata form当您第一次启动应用程序时 -> 显示带有某种用户数据表单的屏幕
  • store the data in a JsonStore -> go to main screen将数据存储在 JsonStore -> go 到主屏幕
  • next time running the app -> check if userdata is in JsonStore and directly go to main screen下次运行应用程序 -> 检查用户数据是否在 JsonStore 中并直接 go 到主屏幕

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:我试过了:

  • using the ScreenManager class (def __init__) - didn't work out使用 ScreenManager class (def __init__) - 没有成功
  • calling a method from within the.kv file like following (not working either):从 .kv 文件中调用方法,如下所示(也不起作用):
<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM