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

Python 两次加载kivy模块时无法编辑文本输入,python,kivy,kivy-language,Python,Kivy,Kivy Language,我正在做一个项目,下面是kivy python模块的流程。视频->登录->主屏幕->视频(重复)。 这是第一次,事物完美地运转 视频播放和点击登录屏幕出现 用户输入凭据,成功登录将他带到主屏幕 用户单击主屏幕上的一个按钮后,重复步骤1 在此之后,登录屏幕上的密码文本框不可编辑,无法继续。在控制台上,它给了我一个信息: [警告][Lang]文件../login.kv以倍数加载 有时候,你可能会有不想要的行为 我正在使用kv文件加载登录屏幕中的控件。我按照其中一个建议将on_parent:self.

我正在做一个项目,下面是kivy python模块的流程。视频->登录->主屏幕->视频(重复)。 这是第一次,事物完美地运转

  • 视频播放和点击登录屏幕出现
  • 用户输入凭据,成功登录将他带到主屏幕
  • 用户单击主屏幕上的一个按钮后,重复步骤1
  • 在此之后,登录屏幕上的密码文本框不可编辑,无法继续。在控制台上,它给了我一个信息:

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

    我正在使用kv文件加载登录屏幕中的控件。我按照其中一个建议将
    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()
    
    #/usr/bin/python3
    #-*-编码:-*-
    从kivy.app导入应用程序
    从kivy.properties导入StringProperty
    从kivy.lang导入生成器
    从kivy.uix.screenmanager导入screenmanager、Screen、SlideTransition
    从kivy.properties导入ObjectProperty、StringProperty
    从pysqlcipher导入dbapi2作为sqlcipher
    导入操作系统,系统
    导入日志记录
    尝试:
    Builder.load_文件(“login.kv”)
    例外情况除外,如e:
    logging.error('login::未能加载kv文件')
    类登录(屏幕):
    用户_id=StringProperty()
    user_pass=StringProperty()
    定义初始(自我,**kwargs):
    超级(登录,自我)。\uuuu初始化
    self.user\u id=self.reset\u user\u id()
    self.user\u pass=self.reset\u user\u pass()
    def重置用户id(自身):
    返回“”
    def重置用户通行证(自我):
    返回“”
    def do_登录(self、loginText、passwordText):
    do\u validation=self.validate(loginText,passwordText)
    如果不进行验证:
    LoginApp.get_running_app().stop()
    尝试:
    Builder.unload_文件(“login.kv”)
    例外情况除外,如e:
    logging.error('卸载kv文件失败')
    从app.HomeScreen导入主屏幕
    HomeScreen.HSApp().run()#运行另一个kivy python模块
    def验证(自我、取消、通过):
    #数据库处理
    返回真值
    def重置表单(自我):
    self.reset\u user\u id()
    self.reset\u user\u pass()
    类登录(应用程序):
    def生成(自):
    返回登录名()
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    LoginApp().run()
    
    以下是登录文件

    <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
    
    :
    盒子布局
    id:login\u布局
    方向:“垂直”
    填充:[10,50,10,50]
    间距:25
    标签:
    文字:“欢迎”
    字号:28
    盒子布局:
    方向:“垂直”
    标签:
    文本:“登录”
    字体大小:14
    哈利格:“左”
    文本大小:root.width-20,20
    文本输入:
    id:登录
    多行:False
    字体大小:14
    身高:14
    提示文字:“输入您的ID”
    在父对象上:self.focus=True
    盒子布局:
    方向:“垂直”
    标签:
    文本:“密码”
    哈利格:“左”
    字体大小:14
    文本大小:root.width-20,20
    文本输入:
    id:密码
    多行:False
    密码:True
    字体大小:14
    身高:14
    提示文字:“输入您的通行证”
    按钮:
    文字:“OK”
    字体大小:14
    按:root.do\u登录(login.text、password.text)
    按钮:
    文本:“重置”
    字体大小:14
    按以下键:root.resetForm()
    标签:
    身份证:身份证
    多行:False
    字体大小:14
    

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

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

    为什么?

    kivy应用程序中的
    屏幕
    与其他应用程序中的
    寡妇
    不同,在其他应用程序中,打开一个新的
    窗口
    基本上就是创建一个新实例,在kivy中只有一个
    窗口
    加载了所有的
    屏幕
    ,一旦你想切换到一个特定的
    屏幕
    ScreenManager
    仅隐藏当前屏幕并显示您请求的屏幕

    我还注意到,您正在为每个
    屏幕运行一个新的应用程序,而应该将所有屏幕添加到同一应用程序中的同一个python模块中

    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
    
    必须更改此代码,如果您没有使用
    屏幕管理器
    ,请查看

    编辑:

    以下是
    屏幕
    屏幕管理器
    工作原理的一个小示例:

    from 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()
    
    从kivy.app导入应用
    从kivy.lang导入生成器
    从kivy.uix.screenmanager导入屏幕,screenmanager
    类登录屏幕(屏幕):
    通过
    类主屏幕(屏幕):
    通过
    SM类(屏幕管理器):
    通过
    app_string=Builder.load_string(“”)
    SM:
    登录筛选:
    主屏幕:
    :
    名称:“登录”
    盒子布局:
    按钮:
    文本:“下一屏幕”
    发布时:
    root.manager.current='home'
    :
    姓名:“家”
    盒子布局:
    按钮:
    文本:“返回登录”
    发布时:
    root.manager.current='login'
    """)
    类别MyApp(应用程序):
    def生成(自):
    返回应用程序字符串
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    MyApp().run()
    

    如果您运行此应用程序,您将在单击按钮时注意到屏幕变化的行为。

    谢谢您的建议。但是,是p吗