Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some troubles using Screen Manager without .kv file

Tags:

python

oop

kivy

I'm trying to make an application with Pthon and kivy. I'm working on the Login/Register part of it. I'm trying to make a screen for each (Login and register) and connect them with the ScreenManager, but WITHOUT .kv file. If it is impossible I'd like to write the less i can in hte .kv file

I've seen some tutorials saying that i had to inherit "Screen" for each window class and create a class for the ScreenManager. Then, at the .kv file, set the 'name' variable for each class. After that, i should use 'root.app.current = ' at the 'on_click' function. I've tryed to do it just with python, and then, with a little bit of KvLang, but it hasn't worked.

I've tried to use the commented part of the code and it hasn't worked too

the .py file

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

the .kv file

#:import FadeTransition kivy.uix.screenmanager.FadeTransition

ScreenManagement:
    transition: FadeTransition()
    RegisterWindow:
        name: 'register'
    LoginWindow:
        name: 'login'

It raises the exception: kivy.uix.screenmanager.ScreenManagerException: No Screen with name "register".

like image 674
1sa4c Avatar asked Oct 27 '25 06:10

1sa4c


1 Answers

You don't actually need any kv at all. Here is a version of your code without 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()

The main changes are the building of the ScreenManagement instance and the child Screens in the App build() method. Also, changed the binding of the Go Button to a screen_transition() method in the same class. And your Screen classes don't need to extend FloatLayout (Screen is a RelativeLayout).

like image 150
John Anderson Avatar answered Oct 28 '25 21:10

John Anderson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!