【问题标题】:Calling FloatLayout class from python file does not work in my kivy file从 python 文件调用 FloatLayout 类在我的 kivy 文件中不起作用
【发布时间】:2020-09-24 18:48:54
【问题描述】:

我一直在研究可以在屏幕(登录屏幕、主屏幕、首选项屏幕)之间切换的 python + kv 脚本,但我遇到了一个我似乎无法自行解决的错误:

Python 脚本

    # 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

# define kv file to call
kv = Builder.load_file('my.kv')

# 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 on_press(self):
        # print is just to check if method is called properly
        print("Username: ", self.username.text, "Password: ", self.password.text)

        """
        Hier komt de verwerking van het inloggen, als het goed is gemaakt door Tim H
        """

        app.root.current = "home" if username.text == "timdadum" and password.text == "mijnwachtwoord" else "login"
        root.manager.transition.direction = "left"

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

    def to_homescreen(self):
        print('Het werkt!')
        """
        Script om naar ander scherm te gaan
        """

# creating application class that consists of  MyFloatLayout
class MyApp(App):
    def build(self):
        return kv

# This if-statement is gibberish for me as well as in idk why this is needed but oh well
if __name__ == '__main__':
    MyApp().run()

kv 文件

WindowManager:
    LoginWindow:
    HomeWindow:
    PreferencesWindow:

<Button>:
    font_size: 27
    size_hint: 0.2, 0.1
    background_color: 0.1, 0.5, 0.6, 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: btn
            text: "Login" if btn.state == "normal" else ""
            on_press: root.on_press()
            color: 1, 1, 1, 1

        Button:
            color: 1, 1, 1, 1
            text: "Home"
            id: to_homescreen
            on_press: root.to_homescreen()
            pos_hint:{'center_x': 0.5, 'center_y': 0.2}

        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"

    Button:
        text: "Go back to login screen"
        on_release:
            app.root.current = "login"
            root.manager.transition.direction = "right"

产生错误:

    raise FactoryException('Unknown class <%s>' % name)
 kivy.factory.FactoryException: Unknown class <MyFloatLayout>

所以我称我的类为“MyFloatLayout”的方式一定有问题。我已经尝试了一切,似乎没有任何效果。如果我将 MyFloatLayout 更改为常规 FloatLayout,它可以正常工作(显然没有我自己的类 MyFloatLayout 的功能)。一些帮助会很棒!

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    kv 文件将按照您命名为my.kv 的命名约定自动加载,不包括MyApp 类的应用程序部分。所以你可以排除/注释掉这一行:

    kv = Builder.load_file('my.kv')
    

    并从return kv 语句中删除kv

    或者您可以将my.kv 文件重命名为任何其他名称,并将kv = Builder.load_file(&lt;kv file name&gt;) 行放在MyFloatLayout 类定义之后。否则会出现unknown class 错误。

    【讨论】:

    • 感谢您的回复!我知道 my.kv 会自动加载一个名为 MyApp 的应用程序。我已经删除了 kv 变量,并且应用程序类 MyApp 不再返回相同的变量。为什么这行得通,而我所没有的?当我更改 kv 变量的名称并使脚本的其余部分保持不变时,它也不起作用。仅仅是因为调用 my.kv 与自动加载 my.kv 冲突吗?
    • 我已经更新了答案。主要问题是在MyFloatLayout 类定义之前加载kv 文件。 kv = Builder.load_file(&lt;kv file name&gt;) 行应该放在 MyFloatLayout 类声明之后。对于使用默认命名约定的 kv 加载,这是自动处理的。对于其他名称的 kv 文件,需要确定 kv 文件加载的位置。希望现在清楚了。
    • 如果使用默认名称my.kv并在MyFloatLayout类定义之前进行显式加载,那么kv文件会被双重加载。自动默认加载会成功,而显式加载会引发unknown class 错误。这正是您的代码发生的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多