How to change label text value in another screen in kivy - python

So I was making an online tic tac toe game using Kivy/KivyMD and im kinda stuck here trying to edit the value of a label of another screen.
here is the main.py
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from requests import get
ip = get('https://api.ipify.org').text
class OptionScreen(Screen):
pass
class JoinServer(Screen):
pass
class CreateServer(Screen):
pass
class WindowManager(ScreenManager):
pass
class TicTacToeApp(MDApp):
def __init__(self, **kwargs):
self.title = "TicTacToe Online"
super().__init__(**kwargs)
def build(self):
TicTacToeApp.build.kv = Builder.load_file('styles\main.kv')
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Gray"
return TicTacToeApp.build.kv
def join(self):
TicTacToeApp.build.kv.current = 'join'
def create(self):
TicTacToeApp.build.kv.current = 'create'
if __name__ == "__main__":
TicTacToeApp().run()
This is the main.kv file:
#:kivy 2.0.0
WindowManager:
OptionScreen:
name: 'option'
JoinServer:
name: 'join'
CreateServer:
name: 'create'
<OptionScreen>:
MDCard:
size_hint: None, None
size: 700, 500
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
spacing: 25
padding: 25
orientation: 'vertical'
MDLabel:
text: "Choose an option"
font_size: "28"
padding_y: 15
size_hint_y: None
halign: 'center'
pos_hint: {'center_x': 0.5,'center_y':0.5}
MDRoundFlatButton:
text:"Join Server"
font_size: 20
pos_hint: {'center_x':0.5}
on_press: app.join()
MDRoundFlatButton:
text:"Create Server"
font_size: 20
pos_hint: {'center_x':0.5}
on_press: app.create()
Widget:
size_hint_y: None
height: 90
<JoinServer>:
MDCard:
size_hint: None, None
size: 700, 500
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
spacing: 25
padding: 25
orientation: 'vertical'
MDLabel:
text: "Join Server"
font_size: "28"
padding_y: 15
size_hint_y: None
halign: 'center'
pos_hint: {'center_x': 0.5,'center_y':0.5}
Widget:
size_hint_y: None
height: 325
<CreateServer>:
MDCard:
size_hint: None, None
size: 700, 500
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
spacing: 25
padding: 25
orientation: 'vertical'
MDLabel:
text: "Create Server"
font_size: 40
padding_y: 15
size_hint_y: None
halign: 'center'
pos_hint: {'center_x': 0.5,'center_y':0.5}
MDLabel:
text: "Server Address: "
id: address
font_size: 18
size_hint_y: None
halign: 'center'
pos_hint: {'center_x': 0.5,'center_y':0.5}
MDTextField:
mode: 'round'
id: passw
hint_text: "Password"
size_hint_x: None
width: 150
font_size: 18
pos_hint: {'center_x': 0.5}
MDRoundFlatButton:
text:"Create Server"
font_size: 20
pos_hint: {'center_x': 0.5}
on_press: app.create_s()
Widget:
size_hint_y: None
height: 20
I want to change the text of the label with the id address in the CreateServer screen to something else as soon as i switch to the CreateServer screen.
I was also wondering how to carry out a code as soon as you switch screens in kivy.

To change the label with the id address in the CreateServer screen simply go the
CreateServer class and do the following changes.
class CreateServer(Screen):
def on_enter(self, *args):
self.manager.get_screen("create").ids.address.text = "your new text value"
and to carry out a code when u switch screens.
use the on_enter function which was used in the answer above. the on_enter function is triggered as soon as the screen becomes active.
I hope it answered your question.

Related

How do I set up a scroll view Kivy?

I'm relatively new to Kivy/KivyMD. I'm currently trying to figure out how to set up a scroll view for one of my screens. As far as I'm aware in order to use a scroll view I need to use a grid layout. Whenever I do this, all the items move to the left of the screen and some of them disappear completely.
Below is an image of the screen I need more space for:
Not enough space
Below is my python file for what I attempted:
import sqlite3
from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivy.lang import Builder
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition
from kivy.uix.scrollview import ScrollView
Builder.load_file('ALevelNEA.kv')
##Below are the classes for my different screens
class SignupScreen(Screen):
pass
class MenuScreen(Screen):
pass
class SigninScreen(Screen, ScrollView):
pass
## Below are the classes for my custom buttons, widgets and text fields
class NameField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class ConfirmPasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class NameField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class PasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class EmailField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
#email_field = ObjectProperty(None)
##Below is the code for my main app
class MainApp(MDApp):
def build(self):
sm = ScreenManager(transition= SwapTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SigninScreen(name = 'signin'))
sm.add_widget(SignupScreen(name='signup'))
return sm
def RecordCheck(self):
print("clicked")
def AddToRecord(self, email, passw):
NewEmail = email
NewPassword = passw
# Connect to or create a new database
conn = sqlite3.connect('example.db')
# Create a cursor object to execute SQL commands
cursor = conn.cursor()
# Create a table to store the records
cursor.execute('''CREATE TABLE IF NOT EXISTS users (email TEXT, password TEXT)''')
# Insert the user's information into the table
cursor.execute("INSERT INTO users (email, password) VALUES (?, ?)", (NewEmail, NewPassword))
# Committing the changes and closing the connection to the database file
conn.commit()
conn.close()
if __name__ == '__main__':
MainApp().run()
Below is the section of my KV file which is relevant for what I attempted:
<SignupScreen>:
ScrollView:
GridLayout:
cols: 1
size_hint_y: None
height: self.minimum_height
padding: dp(10)
spacing: dp(10)
Image:
source: "Images/RegisterImage.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.8 }
MDIconButton:
icon: "keyboard-backspace"
pos_hint: {"center_x": 0.35, "center_y": 0.95}
on_release:
root.manager.current = "menu"
EmailField:
id: email_widget
hint_text: "Email"
pos_hint: {"center_x": 0.5, "center_y": 0.55}
size_hint_x: None
width: "250dp"
NameField:
id: name_widget
hint_text: "Name"
pos_hint: {"center_x": 0.5, "center_y": 0.45}
size_hint_x: None
width: "250dp"
PasswordField:
id: passw_widget
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.35}
ConfirmPasswordField:
id: Cpass_widget
size_hint_x: None
width: "250dp"
hint_text: "Confirm Password"
pos_hint: {"center_x": 0.5, "center_y": 0.25}
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.15}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
#on_release: app.AddToRecord()
on_release:
app.AddToRecord(root.ids.email_widget.ids.email_field.text, root.ids.passw_widget.ids.text_field.text)
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.1}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.0825}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
#Custom buttons and text fields are located below
<PasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<ConfirmPasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<EmailField>:
size_hint_y: None
height: email_field.height
MDTextField:
id: email_field
hint_text: root.hint_text
text: root.text
icon_left: "email"
<NameField>:
size_hint_y: None
height: name_field.height
MDTextField:
id: name_field
hint_text: root.hint_text
text: root.text
icon_left: "account"
Below is the result:
Failed attempt (it does scroll but the layout is wrong)
Any help would be greatly appreciated, thanks!
A GridLayout is not required. Try using a BoxLayout, like this:
<SignupScreen>:
ScrollView:
BoxLayout:
orientation: 'vertical'
# cols: 1

KivyMD: 'super' object has no attribute '__getattr__' during screen transition based on condition

I want to switch from login screen to menu screen based on a successful authentication, but this is the best I could do after a long search on condition-based screen transitions. Most sites say that screen-transitions in kivymd should be done using 'on-release' in .kv file, but I don't think that it would work in my code.
I've marked on the code the problematic line, which is raising the exception.
Teste.py
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.dialog import MDDialog
from kivymd.uix.button import MDFlatButton
from kivy.uix.screenmanager import ScreenManager, Screen
class login(Screen):
pass
class menu(Screen):
pass
Builder.load_file('lteste.kv')
class LoginApp(MDApp):
dialog = None
def build(self): #método construtor da parte visual do aplicativo
self.theme_cls.theme_style = "Light"
self.theme_cls.primary_palette = "Indigo"
self.theme_cls.accent_palette = "Blue"
self.sm = ScreenManager()
self.sm.add_widget(login(name="login"))
self.sm.add_widget(menu(name="menu"))
self.sm.current = "menu"
return self.sm
def dialog_box(self):
if not self.dialog:
self.dialog = MDDialog(
title="Log In",
text=f"Welcome {self.root.ids.user.text}!",
buttons=[MDFlatButton(text="Ok", text_color=self.theme_cls.primary_color,
on_release=self.close),],)
return self.dialog.open()
def login(self):
if self.root.ids.user.text=='1' and self.root.ids.password.text=='1':
self.sm.current = "menu" #<- problem
self.dialog_box()
return True
else:
return False
def close(self, instance):
self.dialog.dismiss()
LoginApp().run()
lteste.kv
<login>:
id: login
name: "login"
MDCard:
size_hint: None, None
size: 300, 600
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
padding: 65
spacing: 35
orientation: 'vertical'
MDIcon:
icon: 'account'
icon_color: 0, 0, 0, 0
halign: 'center'
font_size: 180
MDTextFieldRound:
id: user
icon_left: "account-check"
hint_text: "Usuário"
foreground_color: 1, 0, 1, 1
size_hint_x: None
width: 220
font_size: 20
pos_hint: {"center_x": 0.5}
MDTextFieldRound:
id: password
icon_left: "key-variant"
hint_text: "Senha"
foreground_color: 1, 0, 1, 1
size_hint_x: None
height: 1
width: 220
font_size: 20
pos_hint: {"center_x": 0.5}
password: True
MDFillRoundFlatButton:
text: "ENTRAR"
font_size: 15
pos_hint: {"center_x": 0.5}
on_press: app.login()
MDFillRoundFlatButton:
text: "REGISTRAR-SE"
font_size: 15
pos_hint: {"center_x": 0.5}
<menu>
name: "menu"
id: menu
MDCard:
size_hint: None, None
size: 300, 600
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
padding: 65
spacing: 35
orientation: 'vertical'
MDRaisedButton:
text: "Test"
The application root does not contain the ids you want. They are in the login screen widget because you defined them under it in kivy language. It would help to store a reference on the login screen to access them. Replace
self.sm.add_widget(login(name="login"))
with
self.login_screen = login(name="login")
self.sm.add_widget(self.login_screen)
Then, you can access the widgets like so,
text=f"Welcome {self.login_screen.ids.user.text}!",
and
if self.login_screen.ids.user.text=='1' \
and self.login_screen.ids.password.text=='1':
There is an example in the Kivy Documentation on kivy.uix.widget.Widget.ids and also Accessing Widgets defined inside Kv lang in your Python code.

Either the class "FourthWindow" doesn't show stacklayout or its the only thing on the screen

from kivy.app import App
from kivy.graphics import Line
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivymd.app import MDApp
class ScrollViewExample(ScrollView):
pass
class FirstWindow(Screen):
def set_text(self):
my_title_input = self.ids.note_title
my_details = self.ids.note_details
fo = open("notes.txt", "a")
fo.write('\n'+'\n'+my_title_input.text)
fo.write('\n'+my_details.text)
fo.close()
class SecondWindow(Screen):
pass
class ThirdWindow(Screen):
def on_toggle_button_state(self):
dark_mode = self.ids.dark_mode
dark_mode.text = 'Feature not available'
pass
class FourthWindow(Screen):
#This class displays notes from a file in buttons
#works but only the notes showup
def build(self):
root = FourthWindow()
root.add_widget(FourthWindow(name='StackLayout'))
class StackLayoutExample(StackLayout):
class ScrollView(ScrollView):
pass
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = StackLayout(orientation='lr-tb')
with open('notes.txt', 'r') as fp:
data = fp.read()
splat = data.split("\n\n")
notes = []
for i, note in enumerate(splat, 0):
notes.append(note)
for i in range(0, len(notes)):
b = Button(text=notes[i], size_hint=(.25, .4))
self.add_widget(b)
class WindowManager(ScreenManager):
pass
class RelativeLayoutExample(RelativeLayout):
pass
class ScreeManager(ScreenManager):
pass
class LineMaker(Widget):
pass
class Noteit(App):
pass
Noteit().run()
Noteit.kv <---The kv file begins here
WindowManager:
FirstWindow:
SecondWindow:
ThirdWindow:
FourthWindow:
<FirstWindow>:
id: first_window
name: "Notes"
RelativeLayout:
Label:
text: "Notes"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "left"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "right"
Label:
text: "Title:"
size_hint: None,None
pos_hint: {'top':.85,'center_x':.5}
font_size: 20
TextInput:
id: note_title
size_hint: .45,.08
pos_hint: {'top':.75,'center_x':.5}
multiline: False
Label:
text: "Details:"
size_hint: None,None
pos_hint: {'top':.65,'center_x':.5}
font_size: 20
TextInput:
id: note_details
size_hint: .45,.3
pos_hint: {'top':.55,'center_x':.5}
multiline: True
Button:
text: "Submit"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.25,'center_x':.5}
on_release:
root.set_text()
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
Button:
text: 'View All Notes'
size_hint:.25,.15
pos_hint: {'bottom':1,'center_x':.5}
on_release:
app.root.current = "View"
root.manager.transition.direction= "up"
<SecondWindow>:
name: "Account"
RelativeLayout:
Label:
text: "Account"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "right"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "left"
Label:
text: "Username:"
size_hint: None,None
pos_hint: {'top':.85}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.55,'left':.3}
multiline: False
Label:
text: "Password:"
size_hint: None,None
pos_hint: {'top':.65}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.75,'left':.3}
multiline: False
Button:
text: "Log In"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45}
Button:
text: "Sign Up"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45,'center_x':.375}
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<ThirdWindow>:
name: "Preferences"
RelativeLayout:
Label:
text: "Preferences"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "left"
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "right"
ToggleButton:
text: 'Dark Mode'
size_hint: .25,.1
pos_hint: {'top':.75,'center_x':.25}
on_state: root.on_toggle_button_state()
Label:
id: dark_mode
text: ''
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<FourthWindow>:
name: "View"
RelativeLayout:
Button:
text: 'Note Submission'
size_hint:.25,.15
pos_hint: {'top':1,'center_x':.5}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "down"
Label:
text: 'All Notes'
size_hint: None,None
pos_hint: {'top':1,'right':.9}
font_size: 35
How do I make the stacklayout code showup with the kv file code? Or at least make the stacklayout part of the screen.
Right now the only option I have is either take the screen as output or the stack layout as output.
Replacing the def build(self) inside the class FourthWindow(Screen) will show the whole application. The code inside the def build(self) also works but they do not work together.
I am new to kivy and object oriented programming so I do not know much about this topic so I could be missing something really basic.

kivy : TypeError: 'NoneType' object is not subscriptable in python

When I run this code, it reveals that "TypeError: 'NoneType' object is not subscriptable".
I Want to switch to others screen when I Click to buttons
I'm making a small program and I ran into the error "TypeError: 'NoneType' object is not subscriptable.
I have never before seen this error, so I have no idea what it means.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager , Screen
#define our different screens
class StartTestBtn(Screen):
pass
class TestsResultBtn(Screen):
pass
class SettingBtn(Screen):
pass
class ContactUsBtn(Screen):
pass
class MainPage(Screen):
pass
class WindowManager(ScreenManager):
pass
class MyGridLayout(Widget):
pass
Builder.load_string("""
#:import utils kivy.utils
WindowManager:
MainPage:
StartTestBtn:
TestsResultBtn:
SettingBtn:
ContactUsBtn:
<MainPage>:
name:"main page"
BoxLayout:
cols:1
size: root.width , root.height
spacing: 20
padding: 150
Label:
text: "Welcom"
font_size:72
Button:
text: "start Test"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "startTestBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Tests result"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "TestsResultBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Setting"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "SettingBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Contact Us"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "contactUsBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
<StartTestBtn>:
name: "startTestBtn"
Label:
Text: "start"
font_size: 72
<TestsResultBtn>:
name: "TestsResultBtn"
Label:
Text: "start"
font_size: 72
<SettingBtn>:
name: "SettingBtn"
Label:
Text: "start"
font_size: 72
<ContactUsBtn>:
name: "contactUsBtn"
Label:
Text: "contact"
font_size: 72
""")
class MyLayout(Widget):
pass
class Shenacell(App):
def build(self):
return MyLayout()
if __name__ == '__main__' :
Shenacell().run()
and this is an error :
Traceback (most recent call last):
File "f:/venv/nowornever/Scripts/gui_python.py", line 32, in <module>
Builder.load_string("""
File "C:\Users\Asus\AppData\Roaming\Python\Python38\site-packages\kivy\lang\builder.py", line 373,
in load_string
parser = Parser(content=string, filename=fn)
File "C:\Users\Asus\AppData\Roaming\Python\Python38\site-packages\kivy\lang\parser.py", line 402, in __init__
self.parse(content)
File "C:\Users\Asus\AppData\Roaming\Python\Python38\site-packages\kivy\lang\parser.py", line 511, in parse
objects, remaining_lines = self.parse_level(0, lines)
File "C:\Users\Asus\AppData\Roaming\Python\Python38\site-packages\kivy\lang\parser.py", line 674, in parse_level
if current_property[:3] == 'on_':
TypeError: 'NoneType' object is not subscriptable
Your kv file starts with indentations of 5 spaces, so you must continue that indentation size throughout the kv file. Your last section of kv has incorrect indentation as well as invalid property name (Text should be text). Here is a corrected version of your kv:
#:import utils kivy.utils
WindowManager:
MainPage:
StartTestBtn:
TestsResultBtn:
SettingBtn:
ContactUsBtn:
<MainPage>:
name:"main page"
BoxLayout:
cols:1
size: root.width , root.height
spacing: 20
padding: 150
Label:
text: "Welcom"
font_size:72
Button:
text: "start Test"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "startTestBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Tests result"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "TestsResultBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Setting"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "SettingBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Contact Us"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "contactUsBtn"
size_hint: {'center_x': 0.5}
size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
<StartTestBtn>:
name: "startTestBtn"
Label:
text: "start"
font_size: 72
<TestsResultBtn>:
name: "TestsResultBtn"
Label:
text: "start"
font_size: 72
<SettingBtn>:
name: "SettingBtn"
Label:
text: "start"
font_size: 72
<ContactUsBtn>:
name: "contactUsBtn"
Label:
text: "contact"
font_size: 72
new fixed code
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager , Screen
#define our different screen
class StartTestBtn(Screen):
pass
class TestsResultBtn(Screen):
pass
class SettingBtn(Screen):
pass
class ContactUsBtn(Screen):
pass
class MainPage(Screen):
pass
class WindowManager(ScreenManager):
pass
class MyGridLayout(Widget):
pass
Builder.load_string("""
#:import utils kivy.utils
<WindowManager>:
MainPage:
StartTestBtn:
TestsResultBtn:
SettingBtn:
ContactUsBtn:
<MainPage>:
name:"main page"
BoxLayout:
cols:1
size: root.width , root.height
spacing: 20
padding: 150
Label:
text: "Welcom"
font_size:72
Button:
text: "start Test"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "startTestBtn"
#size_hint: {'center_x': 0.5}
#size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Tests result"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "TestsResultBtn"
#size_hint: {'center_x': 0.5}
#size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Setting"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "SettingBtn"
#size_hint: {'center_x': 0.5}
#size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
Button:
text: "Contact Us"
font_size: 32
size_hint_x: None
height:50
size_hint_y: None
width:200
on_release: app.root.current = "contactUsBtn"
#size_hint: {'center_x': 0.5}
#size_hint: (.5,.5)
background_color : (34/255.0,59/255.0,74/255.0,1)
<StartTestBtn>:
name: "startTestBtn"
Label:
text: "start"
font_size: 72
<TestsResultBtn>:
name: "TestsResultBtn"
Label:
text: "start"
font_size: 72
<SettingBtn>:
name: "SettingBtn"
Label:
text: "start"
font_size: 72
<ContactUsBtn>:
name: "contactUsBtn"
Label:
text: "contact"
font_size: 72
""")
class MyLayout(Widget):
pass
class Shenacell(App):
def build(self):
return WindowManager()
if __name__ == '__main__' :
Shenacell().run()

How to change screens from python code in Kivy

So I'm working on making a fully functional login screen for my first serious kivy app and I want to be able to change windows/screens when the user presses on a button. I know normally in the KV file i'd just use on release but I want the on release to call to a method to verify the users credentials, and if those credentials are correct then change screens. So how in python itself would I be able to call to screen manager to change the screen?
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class LoginLayout(Screen):
def login(self, **kwargs):
print("Login function working")
userEmail = self.ids.username.text
userPassword = self.ids.password.text
print(userEmail)
print(userPassword)
ScreenManager.current('emailWindow')
class EmailWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('loginScreen.kv')
class LoginScreen(App):
def build(self):
return kv
app = LoginScreen()
app.run()
KV
ScreenManager:
LoginLayout:
EmailWindow:
<LoginLayout>:
name: 'loginWindow'
canvas.before:
Color:
rgba: (28/255, 102/255, 137/255, 1)
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size: root.width, root.height
Label:
text: 'Username'
font_name: 'Framd.ttf'
font_size: 20
TextInput:
id: username
multiline: False
size_hint: (.5, .3)
pos_hint: {'center_x' : .5}
Label:
text: 'Password'
font_name: 'Framd.ttf'
font_size: 20
TextInput:
id: password
multiline: False
size_hint: (.5, .3)
pos_hint: {'center_x' : .5}
Button:
text: 'Login'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
font_name: 'Framd.ttf'
on_release: root.login()
Button:
text: 'Create Account'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
font_name: 'Framd.ttf'
Button:
text: 'Forgot login Info'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
font_name: 'Framd.ttf'
<EmailWindow>:
name: 'emailWindow'
canvas.before:
Color:
rgba: (28/255, 102/255, 137/255, 1)
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
size: root.width, root.height
Label:
text: 'To:'
font_name: 'Framd.ttf'
TextInput:
multiline: False
pos_hint: {'center_x': 0.5}
size_hint: (.5, .3)
font_name: 'Framd.ttf'
Label:
text: 'Subject'
TextInput:
multiline: False
pos_hint: {'center_x': 0.5}
size_hint: (.5, .3)
font_name: 'Framd.ttf'
Label:
text: 'Body'
font_name: 'Framd.ttf'
TextInput:
size_hint: (.5, .7)
pos_hint: {'center_x': 0.5}
multiline: True
Button:
text: 'send'
size_hint: (.2, .8)
pos_hint: {'center_x' : 0.5}
font_name: 'Framd.ttf'
When a Screen gets added to a ScreenManager, it gets a manager attribute set to the ScreenManager. So in your login() method you can do:
self.manager.current = 'emailWindow'
instead of:
ScreenManager.current('emailWindow')
Note that using ScreenManager, as you do above, references the ScreenManager class, not the ScreenManager instance that is in your App.

Categories