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".
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With