无法在加载kivy模块时编辑文本输入两次

时间:2017-07-23 10:17:51

标签: python kivy kivy-language

我正在开发一个项目,这里是kivy python模块的流程。视频 - >登录 - > HomeScreen - >视频(重复)。 这是第一次,事情完美无缺,即

  1. 视频播放并点按“登录”屏幕
  2. 用户输入凭据并成功登录将他带到主屏幕
  3. 用户点击主屏幕上的其中一个按钮后,重复步骤1
  4. 此后,“登录”屏幕上的密码文本框将无法使用,无法继续进行。在控制台上,它给了我一条消息:

      

    [警告] [Lang]文件../login.kv加载了倍数   时间,你可能会有不想要的行为。

    我正在使用kv文件在“登录”屏幕中加载控件。我按照blogs之一建议将on_parent:self.focus = True分配给控件,但我有两个。将此属性分配给两个控件(Login和passwd)在第三步之后只能编辑一个。

    以下是我的登录屏幕代码。如果我遗漏任何基本的东西,请告诉我。

    #!/usr/bin/python3
    # -*- coding: <UTF-8> -*-
    
    from kivy.app import App
    from kivy.properties import StringProperty
    from kivy.lang import Builder
    from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
    from kivy.properties import ObjectProperty, StringProperty
    from pysqlcipher import dbapi2 as sqlcipher
    
    import os, sys
    import logging
    
    try:
        Builder.load_file("login.kv")
    except Exception as e:
        logging.error('login::failed to load kv file')
    
    class Login(Screen):
        user_id = StringProperty()
        user_pass = StringProperty()
    
        def __init__(self,  **kwargs):
            super(Login, self).__init__()
            self.user_id = self.reset_user_id()
            self.user_pass = self.reset_user_pass()
    
        def reset_user_id(self):
            return ""
    
        def reset_user_pass(self):
            return ""
    
        def do_login(self, loginText, passwordText):
    
            do_validation = self.validate(loginText, passwordText)
            if do_validation:
                LoginApp.get_running_app().stop()
                try:
                    Builder.unload_file("login.kv")
                except Exception as e:
                    logging.error('failed to unload kv file')
    
                from app.HomeScreen import HomeScreen
                HomeScreen.HSApp().run()    #run another kivy python module
    
        def validate(self, uname, passw):
        #database handling
        return True
    
        def resetForm(self):
            self.reset_user_id()
            self.reset_user_pass()
    
    class LoginApp(App):
        def build(self):
            return Login()
    
    if __name__ == '__main__':
        LoginApp().run()
    

    以下是登录kv文件

    <Login>:
        BoxLayout
            id: login_layout
            orientation: 'vertical'
            padding: [10,50,10,50]
            spacing: 25
    
            Label:
                text: 'Welcome'
                font_size: 28
    
            BoxLayout:
                orientation: 'vertical'
    
                Label:
                    text: 'Login'
                    font_size: 14
                    halign: 'left'
                    text_size: root.width-20, 20
    
                TextInput:
                    id: login
                    multiline:False
                    font_size: 14
                    height: 14
                    hint_text: 'Enter your ID'
                    on_parent:self.focus = True
            BoxLayout:
                orientation: 'vertical'
    
                Label:
                    text: 'Password'
                    halign: 'left'
                    font_size: 14
                    text_size: root.width-20, 20
    
                TextInput:
                    id: password
                    multiline: False
                    password: True
                    font_size: 14
                    height: 14
                    hint_text: 'Enter your pass'
            Button:
                text: 'OK'
                font_size: 14
    
                on_press: root.do_login(login.text, password.text)
    
            Button:
                text: 'Reset'
                font_size: 14
    
                on_press: root.resetForm()
    
            Label:
                id: status
                multiline:False
                font_size: 14
    

    另一个问题是我为各个屏幕多次加载/卸载kv文件。它会产生问题吗?

1 个答案:

答案 0 :(得分:0)

您需要在一个.kv文件中添加所有屏幕配置并加载它。

<强>为什么吗

kivy应用中的

Screens与其他应用中的widows不同,其中打开新的window基本上是创建新实例,在kivy中只有一个window加载了所有screens,一旦您想要更改为特定的screenScreenManager只会隐藏当前的screen并显示您请求的那个。

我还注意到你正在为每个if do_validation: LoginApp.get_running_app().stop() try: Builder.unload_file("login.kv") except Exception as e: logging.error('failed to unload kv file') from app.HomeScreen import HomeScreen HomeScreen.HSApp().run() #run another kivy python module 运行一个新的应用程序,而不是你应该将所有的屏幕添加到同一个应用程序中的同一个python模块。

ScreenManager

此代码必须更改,如果您不使用Screen,请查看this documentation

修改

以下是ScreenManagerfrom kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import Screen, ScreenManager class LoginScreen(Screen): pass class HomeScreen(Screen): pass class SM(ScreenManager): pass app_string = Builder.load_string(""" SM: LoginScreen: HomeScreen: <LoginScreen>: name: 'login' BoxLayout: Button: text: 'Next screen' on_release: root.manager.current = 'home' <HomeScreen>: name: 'home' BoxLayout: Button: text: 'Back to login' on_release: root.manager.current = 'login' """) class MyApp(App): def build(self): return app_string if __name__ == '__main__': MyApp().run() 工作方式的一个小例子:

{{1}}

如果您运行此应用程序,则会在单击按钮时注意到屏幕更改的行为。