在没有 .kv 文件的情况下使用屏幕管理器时出现一些问题

Isa*_*nes 3 python oop kivy

我正在尝试使用 Pthon 和 kivy 制作应用程序。我正在研究其中的登录/注册部分。我试图为每个屏幕(登录和注册)创建一个屏幕,并将它们与 ScreenManager 连接,但没有 .kv 文件。如果不可能,我想在 hte .kv 文件中写尽可能少的内容

我看过一些教程说我必须为每个窗口类继承“Screen”并为 ScreenManager 创建一个类。然后,在 .kv 文件中,为每个类设置“name”变量。之后,我应该在“on_click”函数中使用“root.app.current =”。我尝试仅使用 python 来完成此操作,然后使用一点 KvLang 来完成此操作,但没有成功。

我尝试使用代码的注释部分,但它也不起作用

.py 文件

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition


class ScreenManagement(ScreenManager):
    def __init__(self, **kwargs):
        super(ScreenManagement, self).__init__(**kwargs)
        #self.transition = FadeTransition()
        #self.add_widget(RegisterWindow(name='register'))
        #self.add_widget(LoginWindow(name='login'))

    def screen_transition(self, *args):
        self.current = 'register'


class RegisterWindow(Screen, FloatLayout):
    def __init__(self, **kwargs):
        super(RegisterWindow, self).__init__(**kwargs)
        self.name = 'register'
        self.add_widget(Label(text='Username', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .7}))
        self.username = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .7})
        self.add_widget(self.username)
        self.add_widget(Label(text='Password', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .5}))
        self.password = TextInput(multiline=False, password=True, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .5})
        self.add_widget(self.password)
        self.add_widget(Label(text='E-mail', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .3}))
        self.email = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .3})
        self.add_widget(self.email)
        self.btn = Button(text='Register', size_hint=(.9, .2), pos_hint={'center_x': .5, 'y': .03})
        self.add_widget(self.btn)
        self.btn.bind(on_press=self.submit)

    def submit(self, instance):
        username = self.username.text
        password = self.password.text
        email = self.email.text

        info = {'Username': username,
                'Password': password,
                'Email': email}

        file = open('data.csv', 'a+')
        file.write(f'{info["Username"]},{info["Password"]},{info["Email"]}\n')
        file.close()

        self.username.text = ''
        self.password.text = ''
        self.email.text = ''

        print(info)


class LoginWindow(Screen, FloatLayout):
        def __init__(self, **kwargs):
            super(LoginWindow, self).__init__(**kwargs)
            self.name = 'login'
            self.btn2 = Button(text='Go')
            self.add_widget(self.btn2)
            self.btn2.bind(on_press = ScreenManagement().screen_transition())


class Application(App):
    def build(self):
        return LoginWindow()


if __name__ == "__main__":
    Application().run()
Run Code Online (Sandbox Code Playgroud)

.kv 文件

#:import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:
    transition: FadeTransition()
    RegisterWindow:
        name: 'register'
    LoginWindow:
        name: 'login'
Run Code Online (Sandbox Code Playgroud)

它引发异常:kivy.uix.screenmanager.ScreenManagerException:没有名称为“register”的屏幕。

Joh*_*son 6

你实际上根本不需要任何东西kv。这是您的代码的一个版本,没有kv

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition


class ScreenManagement(ScreenManager):
    def __init__(self, **kwargs):
        super(ScreenManagement, self).__init__(**kwargs)


class RegisterWindow(Screen):
    def __init__(self, **kwargs):
        super(RegisterWindow, self).__init__(**kwargs)
        self.add_widget(Label(text='Username', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .7}))
        self.username = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .7})
        self.add_widget(self.username)
        self.add_widget(Label(text='Password', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .5}))
        self.password = TextInput(multiline=False, password=True, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .5})
        self.add_widget(self.password)
        self.add_widget(Label(text='E-mail', size_hint=(.45, .1), pos_hint={'x': .05, 'y': .3}))
        self.email = TextInput(multiline=False, size_hint=(.45, .1), pos_hint={'x': .5, 'y': .3})
        self.add_widget(self.email)
        self.btn = Button(text='Register', size_hint=(.9, .2), pos_hint={'center_x': .5, 'y': .03})
        self.add_widget(self.btn)
        self.btn.bind(on_press=self.submit)

    def submit(self, instance):
        username = self.username.text
        password = self.password.text
        email = self.email.text

        info = {'Username': username,
                'Password': password,
                'Email': email}

        file = open('data.csv', 'a+')
        file.write(f'{info["Username"]},{info["Password"]},{info["Email"]}\n')
        file.close()

        self.username.text = ''
        self.password.text = ''
        self.email.text = ''

        print(info)


class LoginWindow(Screen):
        def __init__(self, **kwargs):
            super(LoginWindow, self).__init__(**kwargs)
            self.btn2 = Button(text='Go')
            self.add_widget(self.btn2)
            self.btn2.bind(on_press = self.screen_transition)

        def screen_transition(self, *args):
            self.manager.current = 'register'


class Application(App):
    def build(self):
        sm = ScreenManagement(transition=FadeTransition())
        sm.add_widget(LoginWindow(name='login'))
        sm.add_widget(RegisterWindow(name='register'))
        return sm


if __name__ == "__main__":
    Application().run()
Run Code Online (Sandbox Code Playgroud)

主要的变化是实例的构建和方法中的ScreenManagement子实例。此外,还将 的绑定更改为同一类中的方法。并且您的课程不需要扩展(is a )。ScreensApp build()Go Buttonscreen_transition()ScreenFloatLayoutScreenRelativeLayout