Python + Kivy(第二个屏幕正在加载空白)
Python + Kivy (second screen is loading blank)
我正在学习kivy...我正在为一个朋友开发我的第一个应用程序,一个非常简单的应用程序。但我面临这个错误:
每当我单击 "create account" 时,名为 'Login(Screen)' 的内容就会加载为空白。 None 我在我的 kivy 文件上创建的小部件显示。
代码如下:
============================================= =============================
python 文件:
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
def logar(self, usuario, senha):
print("usuario={0}, senha={1}".format(usuario, senha))
class Resultado(Screen):
pass
class LoginApp(App):
def build(self):
return Gerenciador()
LoginApp().run()
============================================= ===========================
kivy 文件:
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta'
Button:
text:'Login'
Button:
text:'Criar nova conta'
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário'
multiline: False
TextInput:
id:senha
hint_text:'Senha'
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
on_press: self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas'
============================================= ============================
关于我遗漏的任何想法?第一个屏幕加载完美。如果我交换订单,登录屏幕加载良好。但是第二个屏幕是空白的,不管是什么内容。只要是加载第二个屏幕,它 returns 空白。
谢谢!
在 Gerenciador
的 __init__()
方法中,您正在创建 Login
和 BoasVindas
屏幕,但您也在 .kv
文件中创建它们.你不应该两者都做。如果您在 .kv
文件中创建它们,您的代码可能如下所示:
python 文件:
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
pass
class Resultado(Screen):
pass
class TesteLogin(App):
def build(self):
return Gerenciador()
TesteLogin().run()
kv 文件:
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta'
Button:
text:'Login'
Button:
text:'Criar nova conta'
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário'
multiline: False
TextInput:
id:senha
hint_text:'Senha'
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
#on_press:self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas'
在您的 .kv
文件中,当 class 名称被 <>
包围时,这意味着它是用于构建 class 的模板,但不是实际上创建 class。不带 <>
的 class 已创建,但 .kv
文件中的那些从属于 Gerenciador
class。因此,当创建 Gerenciador
class 的实例时(如在您的 App.build()
方法中),Login
和 BoasVindas
屏幕将作为其子屏幕创建。请注意,我将 name
属性添加到 .kv
文件中的那些屏幕。
问题 - 第二个屏幕空白
创建了四个屏幕。从 kv 文件创建了两个带有子部件且没有屏幕名称的屏幕。另外两个具有屏幕名称但没有子窗口小部件的屏幕是从 Python 代码创建的。
当按下按钮 'Criar nova conta'
以转到名称为 'login'
的屏幕时,它正在使用从 Python 代码创建的实例,该实例没有任何其中的小部件,即它是空白的。
Build/Processing 序列
在Kivy App中,处理顺序如下。为了证明这一点,将 print() 和 id()
函数添加到 kv 文件中,并为每个屏幕添加 Python 代码和 __init__()
方法。它将显示四个不同的屏幕和每个屏幕的内存位置。
- kv 文件始终是第一个处理的项目。
- Python代码是下一个要处理的项目。
片段:Python代码-证明Build/Processing序列
class Gerenciador(ScreenManager):
def __init__(self):
super(Gerenciador, self).__init__()
print("\nGerenciador.__init__():", id(self), "\n")
self.add_widget(Login(name='login'))
self.add_widget(BoasVindas(name='boasvindas'))
class BoasVindas(Screen):
def __init__(self, **kwargs):
super(BoasVindas, self).__init__(**kwargs)
print("\nBoasVindas.__init__():", id(self), "\n")
class Login(Screen):
def __init__(self, **kwargs):
super(Login, self).__init__(**kwargs)
print("\nLogin.__init__():", id(self), "\n")
class TestLogin(App):
def build(self):
print("\nTestLogin.build():")
return Gerenciador()
片段:文件-证明Build/Processing序列
Button:
text:'Criar nova conta'
on_release:
print("self.parent.parent=", self.parent.parent)
print("id(self.parent.parent)=", id(self.parent.parent))
print("app.root.screen_names=", app.root.screen_names)
print("app.root.screens=", app.root.screens)
for x in app.root.screens: print("screen={0}, id(screen)={1}".format(x, id(x)))
root.current='login'
解决方案
详情请参考分步解决方案和示例。
Python代码
- 用
pass
替换所有构造函数,__init__()
方法
kv 文件
- 将
name
添加到每个屏幕,分别为name: 'boasvindas'
和name: 'login'
。
- 将
self.parent.parent.logar(usuario.text, senha.text)
替换为root.logar(usuario.text, senha.text)
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
def logar(self, usuario, senha):
print("usuario={0}, senha={1}".format(usuario, senha))
class Resultado(Screen):
pass
class TesteLogin(App):
def build(self):
return Gerenciador()
TesteLogin().run()
testelogin.kv
#:kivy 1.11.0
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta' # Sign in or create a new account
Button:
text:'Login'
Button:
text:'Criar nova conta' # Create new account
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário' # User
multiline: False
TextInput:
id:senha
hint_text:'Senha' # Password
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
on_press: self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas' # Welcome
输出
我正在学习kivy...我正在为一个朋友开发我的第一个应用程序,一个非常简单的应用程序。但我面临这个错误:
每当我单击 "create account" 时,名为 'Login(Screen)' 的内容就会加载为空白。 None 我在我的 kivy 文件上创建的小部件显示。
代码如下:
============================================= =============================
python 文件:
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
def logar(self, usuario, senha):
print("usuario={0}, senha={1}".format(usuario, senha))
class Resultado(Screen):
pass
class LoginApp(App):
def build(self):
return Gerenciador()
LoginApp().run()
============================================= ===========================
kivy 文件:
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta'
Button:
text:'Login'
Button:
text:'Criar nova conta'
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário'
multiline: False
TextInput:
id:senha
hint_text:'Senha'
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
on_press: self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas'
============================================= ============================
关于我遗漏的任何想法?第一个屏幕加载完美。如果我交换订单,登录屏幕加载良好。但是第二个屏幕是空白的,不管是什么内容。只要是加载第二个屏幕,它 returns 空白。
谢谢!
在 Gerenciador
的 __init__()
方法中,您正在创建 Login
和 BoasVindas
屏幕,但您也在 .kv
文件中创建它们.你不应该两者都做。如果您在 .kv
文件中创建它们,您的代码可能如下所示:
python 文件:
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
pass
class Resultado(Screen):
pass
class TesteLogin(App):
def build(self):
return Gerenciador()
TesteLogin().run()
kv 文件:
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta'
Button:
text:'Login'
Button:
text:'Criar nova conta'
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário'
multiline: False
TextInput:
id:senha
hint_text:'Senha'
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
#on_press:self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas'
在您的 .kv
文件中,当 class 名称被 <>
包围时,这意味着它是用于构建 class 的模板,但不是实际上创建 class。不带 <>
的 class 已创建,但 .kv
文件中的那些从属于 Gerenciador
class。因此,当创建 Gerenciador
class 的实例时(如在您的 App.build()
方法中),Login
和 BoasVindas
屏幕将作为其子屏幕创建。请注意,我将 name
属性添加到 .kv
文件中的那些屏幕。
问题 - 第二个屏幕空白
创建了四个屏幕。从 kv 文件创建了两个带有子部件且没有屏幕名称的屏幕。另外两个具有屏幕名称但没有子窗口小部件的屏幕是从 Python 代码创建的。
当按下按钮 'Criar nova conta'
以转到名称为 'login'
的屏幕时,它正在使用从 Python 代码创建的实例,该实例没有任何其中的小部件,即它是空白的。
Build/Processing 序列
在Kivy App中,处理顺序如下。为了证明这一点,将 print() 和 id()
函数添加到 kv 文件中,并为每个屏幕添加 Python 代码和 __init__()
方法。它将显示四个不同的屏幕和每个屏幕的内存位置。
- kv 文件始终是第一个处理的项目。
- Python代码是下一个要处理的项目。
片段:Python代码-证明Build/Processing序列
class Gerenciador(ScreenManager):
def __init__(self):
super(Gerenciador, self).__init__()
print("\nGerenciador.__init__():", id(self), "\n")
self.add_widget(Login(name='login'))
self.add_widget(BoasVindas(name='boasvindas'))
class BoasVindas(Screen):
def __init__(self, **kwargs):
super(BoasVindas, self).__init__(**kwargs)
print("\nBoasVindas.__init__():", id(self), "\n")
class Login(Screen):
def __init__(self, **kwargs):
super(Login, self).__init__(**kwargs)
print("\nLogin.__init__():", id(self), "\n")
class TestLogin(App):
def build(self):
print("\nTestLogin.build():")
return Gerenciador()
片段:文件-证明Build/Processing序列
Button:
text:'Criar nova conta'
on_release:
print("self.parent.parent=", self.parent.parent)
print("id(self.parent.parent)=", id(self.parent.parent))
print("app.root.screen_names=", app.root.screen_names)
print("app.root.screens=", app.root.screens)
for x in app.root.screens: print("screen={0}, id(screen)={1}".format(x, id(x)))
root.current='login'
解决方案
详情请参考分步解决方案和示例。
Python代码
- 用
pass
替换所有构造函数,
__init__()
方法
kv 文件
- 将
name
添加到每个屏幕,分别为name: 'boasvindas'
和name: 'login'
。 - 将
self.parent.parent.logar(usuario.text, senha.text)
替换为root.logar(usuario.text, senha.text)
例子
main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
class Gerenciador(ScreenManager):
pass
class BoasVindas(Screen):
pass
class Login(Screen):
def logar(self, usuario, senha):
print("usuario={0}, senha={1}".format(usuario, senha))
class Resultado(Screen):
pass
class TesteLogin(App):
def build(self):
return Gerenciador()
TesteLogin().run()
testelogin.kv
#:kivy 1.11.0
<Gerenciador>:
BoasVindas:
name: 'boasvindas'
BoxLayout:
orientation:'vertical'
Label:
text:'Faça o seu Login ou crie uma nova conta' # Sign in or create a new account
Button:
text:'Login'
Button:
text:'Criar nova conta' # Create new account
on_release:root.current='login'
Login:
name: 'login'
BoxLayout:
TextInput:
id:usuario
hint_text:'Usuário' # User
multiline: False
TextInput:
id:senha
hint_text:'Senha' # Password
multiline: False
password: True
Button:
id:'btn'
text:'Ok'
on_press: self.parent.parent.logar(usuario.text, senha.text)
on_release:root.current='boasvindas' # Welcome