首页 > 解决方案 > 从 kv 文件中的 py 文件调用方法/属性失败

问题描述

我试图check_login()在我的kv文件中调用一个方法,但它未被识别,当我按下kv文件中的第一个按钮时产生此错误:

AttributeError: 'LoginWindow' object has no attribute 'check_login'

这是我的代码:

登录页面GUI.py

# importing library
import kivy

# version
kivy.require('1.11.1')

# importing functionality
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen

# defining screens
class LoginWindow(Screen):
    pass
class PreferencesWindow(Screen):
    pass
class HomeWindow(Screen):
    pass
class WindowManager(ScreenManager):
    pass

# background
Window.clearcolor = (0.67, 0.83, 0.88, 1)

# creating layout class
class MyFloatLayout(FloatLayout):
    username = ObjectProperty(None)
    password = ObjectProperty(None)

    # defining processing method of the login button
    def check_login(self):

        """
        Processing, will fix later
        """

        print("Login succesful!")

        # reset the textinputs to empty strings once pressed and processed
        self.username.text = ''
        self.password.text = ''

        # navigate to home screen
        app.root.current = "home"
        root.manager.transition.direction = "right"

# linking .py with .kv
kv = Builder.load_file('gui.kv')

# creating application class that returns variable kv
class MyApp(App):
    def build(self):
        return (kv)

if __name__ == '__main__':
    MyApp().run()

gui.kv

WindowManager:
    LoginWindow:
    HomeWindow:
    PreferencesWindow:

<Button>:
    font_size: 27
    size_hint: 0.2, 0.1
    background_color: 0.1, 0.5, 0.6, 1
    color: 1, 1, 1, 1
<Label>:
    font_size: 18
    size_hint: 0.1, 0.05
    color: 0.1, 0.5, 0.6, 1
<TextInput>:
    font_size: 14
    size_hint: 0.3, 0.05

<LoginWindow>:
    name: "login"

    MyFloatLayout:
        username: username
        password: password

        Button:
            pos_hint:{'center_y':0.43, 'center_x': 0.5}
            id: to_home
            text: "Login"
            on_press: root.check_login()
            color: 1, 1, 1, 1

        Label:
            pos_hint:{'center_y':0.57, 'center_x': 0.35}
            text: "Username"
        TextInput:
            pos_hint:{'center_y':0.57, 'center_x': 0.6}
            id: username
            multiline: False

        Label:
            pos_hint:{'center_y':0.5, 'center_x': 0.35}
            text: "Password"
        TextInput:
            pos_hint:{'center_y':0.5, 'center_x': 0.6}
            id: password
            multiline: False

<HomeWindow>:
    name: "home"

    MyFloatLayout:
        Button:
            text: "Log out"
            on_release:
                app.root.current = "login"
                root.manager.transition.direction = "right"
            pos_hint:{'center_x': 0.5, 'center_y': 0.57}

        Button:
            text: "Preferences"
            id: to_preferences
            on_release:
                app.root.current = "preferences"
                root.manager.transition.direction = "left"
            pos_hint:{'center_x': 0.5, 'center_y': 0.43}

<PreferencesWindow>
    name: "preferences"

    Button:
        text: "Home"
        id: to_home
        on_release:
            app.root.current = "home"
            root.manager.transition.direction = "right"
        pos_hint:{'center_x': 0.5, 'center_y': 0.43}

    Label:
        text: "To be further processed"

所以不知何故,执行时无法识别login_check()类中的方法MyFloatLayout,从而导致程序失败。我看过SO,但到目前为止还没有发现类似的问题。一些帮助会很棒。

编辑:到目前为止,我刚刚意识到rootis LoginWindow,因为这是我们在这里讨论的按钮的根。我实际上想调用那个根的孩子,MyFloatLayout. 我该怎么做?

标签: pythonkivykivy-language

解决方案


您可以通过MyFloatLayout在 kv 文件中定义一个 id 并通过 id 访问它的功能来做到这一点。更新后的 gui.kv 文件如下:

WindowManager:
    LoginWindow:
    HomeWindow:
    PreferencesWindow:

<Button>:
    font_size: 27
    size_hint: 0.2, 0.1
    background_color: 0.1, 0.5, 0.6, 1
    color: 1, 1, 1, 1
<Label>:
    font_size: 18
    size_hint: 0.1, 0.05
    color: 0.1, 0.5, 0.6, 1
<TextInput>:
    font_size: 14
    size_hint: 0.3, 0.05

<LoginWindow>:
    name: "login"

    MyFloatLayout:
        id: myfloat
        username: username
        password: password

        Button:
            pos_hint:{'center_y':0.43, 'center_x': 0.5}
            id: to_home
            text: "Login"
            on_press: myfloat.check_login()
            color: 1, 1, 1, 1

        Label:
            pos_hint:{'center_y':0.57, 'center_x': 0.35}
            text: "Username"
        TextInput:
            pos_hint:{'center_y':0.57, 'center_x': 0.6}
            id: username
            multiline: False

        Label:
            pos_hint:{'center_y':0.5, 'center_x': 0.35}
            text: "Password"
        TextInput:
            pos_hint:{'center_y':0.5, 'center_x': 0.6}
            id: password
            multiline: False

<HomeWindow>:
    name: "home"

    MyFloatLayout:
        Button:
            text: "Log out"
            on_release:
                app.root.current = "login"
                root.manager.transition.direction = "right"
            pos_hint:{'center_x': 0.5, 'center_y': 0.57}

        Button:
            text: "Preferences"
            id: to_preferences
            on_release:
                app.root.current = "preferences"
                root.manager.transition.direction = "left"
            pos_hint:{'center_x': 0.5, 'center_y': 0.43}

<PreferencesWindow>
    name: "preferences"

    Button:
        text: "Home"
        id: to_home
        on_release:
            app.root.current = "home"
            root.manager.transition.direction = "right"
        pos_hint:{'center_x': 0.5, 'center_y': 0.43}

    Label:
        text: "To be further processed"

但是您的 loginpageGUI.py 文件中也存在一些问题。您需要定义appin__name__块,然后您可以使用app. 另外在功能上需要check_login改成. 更新的 loginpageGUI.py 如下:root.manager.transition.directionapp.root.transition.direction

# importing library
import kivy

# version
kivy.require('1.11.1')

# importing functionality
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen

# defining screens
class LoginWindow(Screen):
    pass
class PreferencesWindow(Screen):
    pass
class HomeWindow(Screen):
    pass
class WindowManager(ScreenManager):
    pass

# background
Window.clearcolor = (0.67, 0.83, 0.88, 1)

# creating layout class
class MyFloatLayout(FloatLayout):
    username = ObjectProperty(None)
    password = ObjectProperty(None)

    # defining processing method of the login button
    def check_login(self):

        """
        Processing, will fix later
        """

        print("Login succesful!")

        # reset the textinputs to empty strings once pressed and processed
        self.username.text = ''
        self.password.text = ''

        # navigate to home screen
        app.root.current = "home"
        app.root.transition.direction = "right"

# linking .py with .kv
kv = Builder.load_file('gui.kv')

# creating application class that returns variable kv
class MyApp(App):
    def build(self):
        return (kv)

if __name__ == '__main__':
    app = MyApp()
    app.run()

推荐阅读