Python + Kivy(第二屏显示为空白)

时间:2018-08-05 20:23:27

标签: python kivy kivy-language

我现在正在学习kivy ...我正在为朋友开发我的第一个应用程序,一个非常简单的应用程序。但是我遇到了这个错误:

每当我单击“创建帐户”时,名为“登录(屏幕)”的内容就会空白。我在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'

================================================ ========================

关于我所缺少的任何想法吗?第一个屏幕完美加载。如果我调换订单,则“登录”屏幕加载良好。但是无论什么内容,第二个屏幕都是空白。只要是第二个要加载的屏幕,它就会返回空白。

谢谢!

2 个答案:

答案 0 :(得分:0)

在用于__init__()的{​​{1}}方法中,您正在创建GerenciadorLogin屏幕,但也将它们放在BoasVindas文件中。您不应该两者都做。如果您在.kv文件中创建它们,则代码如下所示:

python文件:

.kv

kv文件:

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()

在您的<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包围时,这意味着它是用于构建该类的模板,但实际上并未创建该类。创建了没有<>的类,但是<>文件中的类从属于.kv类。因此,在创建Gerenciador类的实例时(如在您的Gerenciador方法中一样),App.build()Login屏幕被创建为其子级。请注意,我在BoasVindas文件的那些屏幕上添加了name属性。

答案 1 :(得分:0)

问题-第二屏空白

创建了四个屏幕。从kv文件创建了两个带有子窗口小部件的屏幕,没有任何屏幕名称。通过Python代码创建了另外两个带有屏幕名称但没有子窗口小部件的屏幕。

按下按钮'Criar nova conta'进入名称为'login'的屏幕时,它使用的是从Python代码创建的实例,该实例中没有任何小部件,即空白。

构建/处理顺序

在Kivy App中,处理顺序如下。为了证明这一点,请在kv文件中添加print()和id()函数,并为每个屏幕添加Python代码__init__()方法。它将分别显示四个不同的屏幕和每个屏幕的存储位置。

  1. kv文件始终是第一个处理的项目。
  2. Python代码是下一个要处理的项目。

代码段:Python代码-证明构建/处理顺序

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()

代码段:文件-验证构建/处理顺序

        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代码

  1. 将所有构造函数__init__()方法替换为pass

kv文件

  1. 向每个屏幕分别添加namename: 'boasvindas' name: 'login'
  2. 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

输出

Img01 - Second Screen