两次加载 kivy 模块时无法编辑文本输入
Unable to edit text input on loading kivy module twice
我正在做一个项目,这里是 kivy python 模块的流程。视频 -> 登录 -> 主屏幕 -> 视频(重复)。
第一次,一切都完美无缺,即
- 视频播放并点击登录屏幕出现
- 用户输入凭据并成功登录后会转到主屏幕
- 一旦用户点击主屏幕上的按钮之一,重复步骤 1
在此之后,登录屏幕上的密码文本框不可编辑,无法继续。在控制台上它给了我一条消息:
[WARNING] [Lang ] The file ../login.kv is loaded multiples
times, you might have unwanted behaviors.
我正在使用 kv 文件加载登录屏幕中的控件。我按照 blogs 的建议之一将 on_parent:self.focus = True
分配给控件,但我有两个。将此 属性 分配给两个控件(登录名和密码)使得在第三步之后只有一个可编辑。
以下是我的登录屏幕代码。如果我遗漏了任何基本内容,请告诉我。
#!/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
另一个问题是我 loading/unloading kv 文件多次用于各个屏幕。它会产生问题吗?
您需要将所有屏幕配置添加到一个 .kv
文件中并加载它。
为什么?
Screens
在 kivy 应用程序中不像 widows
在其他应用程序中打开一个新的 window
基本上是创建一个新实例,在 kivy 中只有一个 window
加载了所有 screens
,一旦您想更改为特定的 screen
,ScreenManager
只会隐藏当前的并显示您请求的那个。
我还注意到您运行为每个 screen
创建了一个新应用程序,您应该将所有屏幕添加到同一个应用程序中的同一个 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
此代码必须更改,如果您不使用 ScreenManager
请查看 this documentation。
编辑:
下面是 Screen
和 ScreenManager
如何工作的一个小例子:
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 python 模块的流程。视频 -> 登录 -> 主屏幕 -> 视频(重复)。 第一次,一切都完美无缺,即
- 视频播放并点击登录屏幕出现
- 用户输入凭据并成功登录后会转到主屏幕
- 一旦用户点击主屏幕上的按钮之一,重复步骤 1
在此之后,登录屏幕上的密码文本框不可编辑,无法继续。在控制台上它给了我一条消息:
[WARNING] [Lang ] The file ../login.kv is loaded multiples times, you might have unwanted behaviors.
我正在使用 kv 文件加载登录屏幕中的控件。我按照 blogs 的建议之一将 on_parent:self.focus = True
分配给控件,但我有两个。将此 属性 分配给两个控件(登录名和密码)使得在第三步之后只有一个可编辑。
以下是我的登录屏幕代码。如果我遗漏了任何基本内容,请告诉我。
#!/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
另一个问题是我 loading/unloading kv 文件多次用于各个屏幕。它会产生问题吗?
您需要将所有屏幕配置添加到一个 .kv
文件中并加载它。
为什么?
Screens
在 kivy 应用程序中不像 widows
在其他应用程序中打开一个新的 window
基本上是创建一个新实例,在 kivy 中只有一个 window
加载了所有 screens
,一旦您想更改为特定的 screen
,ScreenManager
只会隐藏当前的并显示您请求的那个。
我还注意到您运行为每个 screen
创建了一个新应用程序,您应该将所有屏幕添加到同一个应用程序中的同一个 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
此代码必须更改,如果您不使用 ScreenManager
请查看 this documentation。
编辑:
下面是 Screen
和 ScreenManager
如何工作的一个小例子:
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()
如果你运行这个应用程序,你会注意到点击按钮时屏幕变化的行为。