I have this application where user enters his/her username. When the submit button is clicked, another page loads where the previous username entered should be displayed into an uneditable textbox. I have attached the full code below. How can I make the load_username textInput get the username textInput from the user page?
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string("""
<User>:
username:username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Enter username below'
TextInput:
id: username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Get username'
on_press:
root.save_username()
root.manager.current = 'get_user'
""")
Builder.load_string("""
<GetUser>:
load_username:load_username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Received username from previous page'
TextInput:
id: load_username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
disabled:True
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Go back to username page'
on_press:
root.manager.current = 'user'
root.get_username()
""")
class User(Screen):
pass
def save_username(self):
print('saved: ', self.username.text)
class GetUser(Screen):
pass
def get_username(self):
self.load_username.text = "This should be previous username"
sm = ScreenManager()
sm.add_widget(User(name='user'))
sm.add_widget(GetUser(name='get_user'))
class UserName(App):
def build(self):
return sm
if __name__ == '__main__':
UserName().run()
You have to find a way to assign the text to the next screen when clicking the get username button.
Working code below:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
Builder.load_string("""
<User>:
username:username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Enter username below'
TextInput:
id: username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Get username'
on_press:
root.save_username()
root.set_username()
root.manager.current = 'get_user'
<GetUser>:
load_username:load_username
user_label:user_label
but_1:but_1
# cols: 1
Label:
id: user_label
font_size: 30
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
text:'Received username from previous page'
TextInput:
id: load_username
font_size: 30
pos_hint:{"x":0.3,"y":0.25}
size_hint: 0.4, 0.07
color: 0.6, 0.6, 0.6, 1
text_size: self.width, None
halign: 'center'
disabled:True
Button:
id: but_1
font_size: 20
pos_hint:{"x":0.3,"y":0.15}
size_hint: 0.4, 0.07
text: 'Go back to username page'
on_press:
root.manager.current = 'user'
""")
class User(Screen):
def save_username(self):
print('saved: ', self.username.text)
def set_username(self): # <--- Asign the name here
screens = App.get_running_app().root.screens
other_screen = None
text = ""
for screen in screens:
if screen.name == "user":
text = screen.username.text
elif screen.name == "get_user":
other_screen = screen
other_screen.load_username.text = text
class GetUser(Screen):
pass
sm = ScreenManager()
sm.add_widget(User(name='user'))
sm.add_widget(GetUser(name='get_user'))
class UserName(App):
def build(self):
return sm
if __name__ == '__main__':
UserName().run()
Related
Hiii ^_^.
I am a beginner in python and kivy and I decided to learn by building an application with registration and login after which it will transfer me to the game. The game is based on images displayed through ScreenManager. All good so far. The code for the interface with menu, registration and logging is in another project and the one with the game in another, so I decided to combine them, I mostly succeeded but I got stuck at the step where it sends me to the first screen of the game and from there pressing a button to generate a Screen randomly I get this error
~~ AttributeError: 'MyMainApp' object has no attribute 'random_screen' ~~
I have tried all kinds of solutions to solve this problem, but I can't figure it out in any way.
Can someone tell me where I am wrong?
If I add the code lines with random_screen in the MyMainApp class, nothing happens..
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from database import DataBase
import random
class CreateAccountWindow(Screen):
namee = ObjectProperty(None)
email = ObjectProperty(None)
password = ObjectProperty(None)
def submit(self):
if self.namee.text != "" and self.email.text != "" and self.email.text.count("#") == 1 and self.email.text.count(".") > 0:
if self.password != "":
db.add_user(self.email.text, self.password.text, self.namee.text)
self.reset()
sm.current = "login"
else:
invalidForm()
else:
invalidForm()
def login(self):
self.reset()
sm.current = "login"
def reset(self):
self.email.text = ""
self.password.text = ""
self.namee.text = ""
class LoginWindow(Screen):
email = ObjectProperty(None)
password = ObjectProperty(None)
def loginBtn(self):
if db.validate(self.email.text, self.password.text):
MainWindow.current = self.email.text
self.reset()
sm.current = "main"
else:
invalidLogin()
def createBtn(self):
self.reset()
sm.current = "create"
def reset(self):
self.email.text = ""
self.password.text = ""
class MainWindow(Screen):
n = ObjectProperty(None)
created = ObjectProperty(None)
email = ObjectProperty(None)
current = ""
def logOut(self):
sm.current = "login"
class Q1(Screen):
pass
class Q2(Screen):
pass
class Q3(Screen):
pass
class Q4(Screen):
pass
class WrongAnswer(Screen):
pass
class TestApp:
def wrong_answer(self):
screen = ['WrongAnswer']
return random.choice(screen)
def random_screen(self):
screens = ['Q1', 'Q2', 'Q3', 'Q4']
return random.choice(screens)
def build(self):
sm = ScreenManager()
sm.add_widget(Q1(name='Q1'))
sm.add_widget(Q2(name='Q2'))
sm.add_widget(Q3(name='Q3'))
sm.add_widget(Q4(name='Q4'))
sm.add_widget(WrongAnswer(name='WrongAnswer'))
return sm
class WindowManager(ScreenManager):
pass
def invalidLogin():
pop = Popup(title='Invalid Login',
content=Label(text='Invalid username or password.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def invalidForm():
pop = Popup(title='Invalid Form',
content=Label(text='Please fill in all inputs with valid information.'),
size_hint=(None, None), size=(400, 400))
pop.open()
kv = Builder.load_file("my.kv")
sm = WindowManager()
db = DataBase("users.txt")
screens = [LoginWindow(name="login"), CreateAccountWindow(name="create"),MainWindow(name="main"),Q1(name="start")]
for screen in screens:
sm.add_widget(screen)
sm.current = "login"
class MyMainApp(App):
def build(self):
return sm
if __name__ == "__main__":
MyMainApp().run()
<CreateAccountWindow>:
name: "create"
namee: namee
email: email
password: passw
FloatLayout:
cols:1
FloatLayout:
size: root.width, root.height/2
Label:
text: "Create an Account"
size_hint: 0.8, 0.2
pos_hint: {"x":0.16, "top":1}
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8}
text: "Name: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
id: namee
multiline: False
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.13}
text: "E-Mail: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.65}
size_hint: 0.4, 0.075
id: email
multiline: False
font_size: (root.width**2 + root.height**2) / 14**4
Label:
size_hint: 0.5,0.12
pos_hint: {"x":0, "top":0.8-0.125*2}
text: "Password: "
font_size: (root.width**2 + root.height**2) / 14**4
TextInput:
pos_hint: {"x": 0.38, "top":0.53}
size_hint: 0.4, 0.075
id: passw
multiline: False
password: True
font_size: (root.width**2 + root.height**2) / 14**4
Button:
pos_hint:{"x":0.60,"y":0.35}
size_hint: 0.18, 0.075
font_size: (root.width**2.11 + root.height**2) / 17**4
text: "Back to Login"
on_release:
root.manager.transition.direction = "left"
root.login()
Button:
pos_hint:{"x":0.38,"y":0.35}
size_hint: 0.18, 0.075
text: "Register"
font_size: (root.width**1.95 + root.height**2) / 14**4
on_release:
root.manager.transition.direction = "left"
root.submit()
<LoginWindow>:
name: "login"
email: email
password: password
FloatLayout:
Label:
text:"E-Mail: "
font_size: (root.width**1.8 + root.height**2) / 13**4
pos_hint: {"x":0.1, "top":0.9}
size_hint: 0.40, 0.15
TextInput:
id: email
font_size: (root.width**1.91 + root.height**2) / 13**4
multiline: False
pos_hint: {"x": 0.38 , "top":0.86}
size_hint: 0.4, 0.075
Label:
text:"Password: "
font_size: (root.width**1.8 + root.height**2) / 13**4
pos_hint: {"x":0.106, "top":0.81}
size_hint: 0.35, 0.15
TextInput:
id: password
font_size: (root.width**1.91 + root.height**2) / 13**4
multiline: False
password: True
pos_hint: {"x": 0.38, "top":0.77}
size_hint: 0.4, 0.075
Button:
pos_hint:{"x":0.38,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**1.8 + root.height**2) / 13**4
text: "Login"
on_release:
root.manager.transition.direction = "up"
root.loginBtn()
Button:
pos_hint:{"x":0.60,"y":0.605}
size_hint: 0.18, 0.075
font_size: (root.width**2.09 + root.height**2) / 17**4
text: "Create Account"
on_release:
root.manager.transition.direction = "right"
root.createBtn()
<MainWindow>:
FloatLayout:
Button:
pos_hint:{"x": 0.6, "top":0.9}
size_hint:0.4, 0.1
text: "5 Players"
Button:
pos_hint:{"x": 0.6, "top":0.7}
size_hint:0.4, 0.1
text: "10 Players"
Button:
pos_hint:{"x": 0.6, "top":0.5}
size_hint:0.4, 0.1
text: "15 Players"
Button:
pos_hint:{"x": 0.6, "top":0.3}
size_hint:0.4, 0.1
text: "20 Players"
on_release:
app.root.current = "start"
root.manager.transition.direction = "down"
Button:
pos_hint:{"x":0.04, "y": 0.05}
size_hint:0.2,0.1
text: "Log Out"
on_release:
app.root.current = "login"
root.manager.transition.direction = "down"
<Q1>:
name: "start"
Image:
source: 'Q1.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q2>:
Image:
source: 'Q2.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<Q3>:
Image:
source: 'Q3.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
<Q4>:
Image:
source: 'Q4.png'
FloatLayout:
size: root.width, root.height/2
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.random_screen()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":1.16}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.5, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
Button:
size_hint: 0.3, 0.25
pos_hint: {"x":0.09, "top":0.7}
background_color: 1, 1, 1, 0.2
on_release: root.manager.current = app.wrong_answer()
<WrongAnswer>:
Image:
source: 'L1.png'
You already knew what is the cause. in mymainapp class, you don't have the attirube: random_screen. random_screen is in class TestApp.
if you want that attribute exist in mymainapp class, you can use multiple inherit. like this:
class MyMainApp(App, TestApp):
def build(self):
return sm
Your random_screen function is in TestApp, which you don't use for anything. Instead, your app seems to be MyMainApp.
You can
move the contents of TestApp to MyMainApp (and get rid of TestApp),
or the other way around, make TestApp inherit from App and move the build method there, then use TestApp instead of MyMainApp.
Based on an input (0, 1, 2 or 3) the kv.file or py.file should add a group of Toggle Buttons to the already existing layout. I tried a lot but can't seem to figure it out and would love some advice, since it is all still a bit new to me.
So when self.reminder() = 0, no Toggle Buttons are shown.
When self.reminder() = 1, one group of Toggle Buttons is shown.
When self.reminder() = 2, two groups of Toggle Buttons are shown.
When self.reminder() = 3, three groups of Toggle Buttons are shown.
self.reminder() will not excess the value of 3.
So I have got my .py file
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
import csv
from kivy.core.window import Window
class WindowManager(ScreenManager):
pass
#Backgroundcolour
Window.clearcolor = (0.67, 0.83, 0.88, 1)
class DiaryToday(Screen):
user_id = 3
# reads how many reminders (aka Toggle Buttons) the user wants from csv file
# used for textlabel, this textlabel will not show if reminder == 0 (is stated in kv file)
def reminder(self):
with open('users.csv') as file: #TO DO: needs to be adjusted to global ID
reader = csv.DictReader(file)
for row in reader:
if row['id'] == str(self.user_id): #TO DO: needs to be adjusted to global ID
if row['mood_rem'] == 'Zero':
return(0)
else:
return(row['mood_rem'][0])
# TO DO: STORES in CSV file which emoji you clicked
def mood_value(self, mood):
print (mood)
#Takes care of which group of ToggleButtons is shown in the Diary Screen
def add(self):
if root.reminder() == 0:
#should add or show no Toggle Buttons
if root.reminder() == 1:
#should add or show 1 set of Toggle Buttons
if root.reminder() == 2:
#should add or show 2 sets of Toggle Buttons
if root.reminder()== 3:
#should add or show 3 sets of Toggle Buttons
class LoopApp(App):
def build(self):
return DiaryToday()
if __name__ == '__main__':
LoopApp().run()
And my .kv file
<DiaryToday>:
name: "diarytoday"
answer: answer
diaryinput: diaryinput
id: test
FloatLayout:
Button:
background_color: 0.1, 0.5, 0.6, 1
pos_hint:{'center_y':0.05, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
text: "Save"
Button:
pos_hint:{'center_y':0.95, 'center_x': 0.175}
background_color: 0.1, 0.5, 0.6, 1
font_size: 18
size_hint: 0.15, 0.05
text: "Previous day"
Label:
pos_hint:{'center_y':0.95, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'date'
font_size: 22
Label:
pos_hint:{'center_y':0.87, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'Question'
TextInput:
font_size: 14
size_hint: 0.8, 0.1
pos_hint:{'center_y':0.78, 'center_x': 0.5}
id: answer
Label:
pos_hint:{'center_y':0.67, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: 'My Diary'
TextInput:
font_size: 14
size_hint: 0.8, 0.22
pos_hint:{'center_y':0.51, 'center_x': 0.5}
id: diaryinput
Label:
pos_hint:{'center_y':0.36, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: ' ' if root.reminder() == 0 else 'How are you feeling?'
BoxLayout:
id: ToggleButtonGroup1
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, 0.1
ToggleButton:
background_normal: 'VerysadEmoji1.png'
background_down: 'VerysadEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(1)
ToggleButton:
background_normal: 'SadEmoji1.png'
background_down: 'SadEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(2)
ToggleButton:
background_normal: 'MediumEmoji1.png'
background_down: 'MediumEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(3)
ToggleButton:
background_normal: 'HappyEmoji1.png'
background_down: 'HappyEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(4)
ToggleButton:
background_normal: 'VeryHappyEmoji1.png'
background_down: 'VeryHappyEmoji2.png'
group: "emojis"
size_hint: 0.5, 1.3
on_press: root.mood_value(5)
Label:
pos_hint:{'center_y':0.19, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: "Here will come Toggle Button Group 2"
Label:
pos_hint:{'center_y':0.12, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: "Here will come Toggle Button Group 3"
Thanks!
You can define a class that is the Toggle Button Group that you want to add. Something like this:
class SomeToggles(BoxLayout):
group = StringProperty('') # this will be the group for the ToggleButtons
Then the add() method can be:
#Takes care of which group of ToggleButtons is shown in the Diary Screen
def add(self):
if self.reminder() == 0:
print('0')
#should add or show no Toggle Buttons
if self.reminder() == 1:
print('1')
self.ids.toggles.add_widget(SomeToggles(group=str(self.grp_count)))
self.grp_count += 1
#should add or show 1 set of Toggle Buttons
if self.reminder() == 2:
print('2')
#should add or show 2 sets of Toggle Buttons
if self.reminder()== 3:
print('3')
#should add or show 3 sets of Toggle Buttons
The above only handles the case where self.reminder() returns 1, but the others would be similar. Of course, the grp_count (which is just a construct of mine to define the group property) needs to be added:
class DiaryToday(Screen):
grp_count = 0
For this to work, a container with id of toggles must be defined. This will be another BoxLayout that contains the first set of Toggle Buttons as well as the added ones. So the modified kv file looks like:
<DiaryToday>:
name: "diarytoday"
answer: answer
diaryinput: diaryinput
id: test
FloatLayout:
Button:
background_color: 0.1, 0.5, 0.6, 1
pos_hint:{'center_y':0.05, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
text: "Save"
Button:
pos_hint:{'center_y':0.95, 'center_x': 0.175}
background_color: 0.1, 0.5, 0.6, 1
font_size: 18
size_hint: 0.15, 0.05
text: "Previous day"
Label:
pos_hint:{'center_y':0.95, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'date'
font_size: 22
Label:
pos_hint:{'center_y':0.87, 'center_x': 0.5}
font_size: 18
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
text: 'Question'
TextInput:
font_size: 14
size_hint: 0.8, 0.1
pos_hint:{'center_y':0.78, 'center_x': 0.5}
id: answer
Label:
pos_hint:{'center_y':0.67, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: 'My Diary'
TextInput:
font_size: 14
size_hint: 0.8, 0.22
pos_hint:{'center_y':0.51, 'center_x': 0.5}
id: diaryinput
Label:
pos_hint:{'center_y':0.36, 'center_x': 0.5}
size_hint: 0.1, 0.05
color: 0.1, 0.5, 0.6, 1
font_size: 18
text: ' ' if root.reminder() == 0 else 'How are you feeling?'
BoxLayout: # this contains all the Toggle Button groups
id: toggles
orientation: 'vertical'
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint_y: None
height: self.minimum_height
BoxLayout:
id: ToggleButtonGroup1
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, None
height: self.minimum_height
ToggleButton:
background_normal: 'VerysadEmoji1.png'
background_down: 'VerysadEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(1)
ToggleButton:
background_normal: 'SadEmoji1.png'
background_down: 'SadEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(2)
ToggleButton:
background_normal: 'MediumEmoji1.png'
background_down: 'MediumEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(3)
ToggleButton:
background_normal: 'HappyEmoji1.png'
background_down: 'HappyEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(4)
ToggleButton:
background_normal: 'VeryHappyEmoji1.png'
background_down: 'VeryHappyEmoji2.png'
group: "emojis"
size_hint: 0.5, None
height: 40
on_press: root.mood_value(5)
<SomeToggles>:
pos_hint: {'center_y':0.26, 'center_x': 0.5}
size_hint: 0.5, None
height: self.minimum_height
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
ToggleButton:
group: root.group
size_hint: 0.5, None
height: 40
The above kv also includes the <SomeToggles> rule that defines how the new Toggle Button group is built. You will also need to provide a mechanism for calling self.reminder(). I just added that call to the mood_value() method.
I'm pretty new to python and kivy and I'm trying to build my first app for my masterthesis. The problem I'm struggeling with right now is that I have multiple python and kivy files, and my app includes a group of Toggle buttons and Spinners. I want to 'store'/assign theselected values and print them when i hit my submit button. I'm working with multiple python and kivy files. The app also has some sliders and i managed to get those values when pressing submit, but can't figure it out for toggles nor spinners. I hope you can help!:)
Main .py, rather important:
import kivy
from kivy.app import App
from kivy.uix.button import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
Builder.load_file('Header.kv')
Builder.load_file('Statusbar.kv')
Builder.load_file('Inputparameters.kv')
Builder.load_file('Outputparameters.kv')
#Layout
class Peenomat(AnchorLayout):
def show_selected_value(self, spinner, text):
print(spinner, text)
#pass
#DropDown in Inputparameters
#class InputParameters(BoxLayout):
#state = BooleanProperty(False)
class PeenomatApp(App):
def build(self):
return Peenomat()
if __name__=="__main__":
PeenomatApp().run()
The main kv file:
AnchorLayout:
anchor_x: 'left'
anchor_y: 'bottom'
GridLayout:
cols: 1
canvas.before:
Color:
rgba: 0.75 ,0.75, 0.75, 1
Rectangle:
pos: self.pos
size: self.size
Header:
id: _header
size_hint: 1, 0.1
#height: 100
InputParameters:
id:_input_parameters
size_hint: 1, 0.45
StatusBar:
id:_status_bar
size_hint: 1, 0.1
#height: 50
OutputParameters:
id:_output_parameters
size_hint: 1, 0.35
The .kv file that includes the toogle buttons, spinners, and sliders where i guess most of the implemantation needs to be done
#: import statusbar StatusBar
<InputParameters#GridLayout>
prozess: _proz_value
prozess1: _prozess1
prozess2: _prozess2
prozess3: _prozess3
vorbehandlung: _vorbehandlung
material: _material
haerte: _haerte
rauheit: _rauheit
cols: 2
padding: 15
spacing: 15
#Farbe Schrift Label
cb: (1,1, 1,1)
#Farbe Slider
cs: (0,0.353, 0.663,1)
#FontSize
fs: 20
#Prozess
Label:
text:'Prozess: '
bold: True
font_size: root.fs
text_size: self.size
halign: 'left'
valign: 'center'
color: root.cb
BoxLayout:
orientation: 'horizontal'
id: _proz_value
_proz_value: 0
ToggleButton:
text:'P-MOH'
id: _prozess1
group: "proc_group"
background_color: 0.0, 0.353, 0.663, 1.0
bold: True
on_press: root._proz_value = 1
ToggleButton:
text:'E-MOH'
id: _prozess2
group: "proc_group"
background_color: 0.0, 0.353, 0.663, 1.0
bold: True
on_press: root._proz_value = 2
ToggleButton:
text:'PE-MOH'
id: _prozess3
group: "proc_group"
background_color: 0.0, 0.353, 0.663, 1.0
bold: True
on_press: root._proz_value = 3
#Material
Label:
text: 'Material: '
bold: True
font_size: root.fs
text_size: self.size
halign: 'left'
valign: 'center'
color: root.cb
Spinner:
id: _material
# Callback
on_text:
text: "Auswahl treffen"
bold:True
values: ['1.2379', 'Gusseisen', 'Kautschuk', 'Carbon', 'Adamantium']
#background_normal: '[1,1,1,1]'
background_color: root.cs
color: root.cb
# Herstellschritte
Label:
text:'Fertigungsschritte: '
bold: 'True'
font_size: root.fs
text_size: self.size
halign: 'left'
valign: 'center'
color: root.cb
Spinner:
id: _vorbehandlung
# Callback
on_text:
app.root.show_selected_value(self, self.text)
text: "Auswahl treffen"
bold:True
values: ['Fräsen', 'Erodieren', 'Schleifen', 'Polieren']
#background_normal: '[1,1,1,1]'
background_color: root.cs
color: root.cb
# Haerte
Label:
text:'Haerte: '
bold: True
font_size: root.fs
text_size: self.size
halign: 'left'
valign: 'center'
color: root.cb
BoxLayout:
orientation: 'vertical'
spacing: 15
Label:
text: str(_haerte.value) + ' HRC'
color: root.cs
bold: True
Slider:
id: _haerte
min: 45
max: 65
value:55
step: 1
value_track: True
value_track_color: root.cs
# Rauheit
Label:
text:'Rauheit: '
#color: cb
bold: True
font_size: root.fs
text_size: self.size
halign: 'left'
valign: 'center'
color: root.cb
BoxLayout:
orientation: 'vertical'
spacing: 15
Label:
text: str("%.1f" % _rauheit.value) + ' Rz' #eine Nachkommastelle
color: root.cs
bold: True
Slider:
id: _rauheit
min: 1
max: 10
value:5.5
step: 0.1
value_track: True
value_track_color: root.cs
The .kv file that includes the submit button:
#: import statusbar StatusBar
<StatusBar#BoxLayout>
orientation:'horizontal'
padding: 5
fs: 16
Button:
text: 'Clear'
background_color: 0.0, 0.353, 0.663, 1.0
size_hint: 0.4, 1
bold: True
font_size: 20
on_press: root.btn_clear()
Button:
text: 'Submit'
background_color: 0.0, 0.353, 0.663, 1.0
size_hint: 0.4, 1
bold: True
font_size: 20
on_press: root.btn_submit()
and last but not the least the file that includes the methods that are assigned to the buttons, which shuld also be important for my issue:
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.app import App
from kivy.lang import Builder
class StatusBar(BoxLayout):
group_mode = False
#translation = ListProperty(None)
prozess = ObjectProperty(None)
vorbehandlung = ObjectProperty(None)
material = ObjectProperty(None)
haerte = ObjectProperty(None)
rauheit = ObjectProperty(None)
def btn_submit(self,text):
ip = App.get_running_app().root.ids._input_parameters
print("Haerte:", ip.haerte.value, "Rauheit:", ip.rauheit.value, "Material:", ip.material.text)
def btn_clear(self):
np = App.get_running_app().root.ids._input_parameters
np.prozess1.state = "normal"
np.prozess2.state = "normal"
np.prozess3.state = "normal"
np.material.text = "Auswahl treffen"
np.haerte.value = 55
np.rauheit.value = 5.5
The App is running like this and the clear button is exactly doing what its supposed to do, but I really can't figure out how I manage to print the selected spinner and toggle values when hitting submit...I hope you guys can help, been struggeling with this since a while now. Thanks in advance!
Alright i figured out an easy way to get the spinner value when hititng submit:
def btn_submit(self):
ip = App.get_running_app().root.ids._input_parameters
print("Haerte:", ip.haerte.value, "Rauheit:", ip.rauheit.value, "Material:", ip.material.text, "Vorbehandlung:", ip.vorbehandlung.text)
to get the value of the toggle buttons i did this:
def on_state(self, togglebutton):
tb = togglebutton
if tb.state == 'down':
self.verfahren = tb.text
InputParameters.verfahren = tb.text
print(self.verfahren)
return InputParameters.verfahren
and added in the .kv file for the toggle button:
ToggleButton:
id:_prozess2
text:'E-MOH'
on_state: root.on_state(self)
I'm getting the value/state like that, but it's not triggered with the submit button, can't figure out how to do so
What I'm trying to achieve here is to change the color button in the SurveyHeader widget after clicking either checkboxes. Example: after checking any checkboxes in question 3, I would like only button number "3" to turn red. Also, after clicking next, I would like the button number "3" to remain red. This is where I'm having a hard time., after switching screens, my button color changes to the original color. Is it because I'm creating a new instance of QuestionsScreen1 everytime? If so, is there any workaround for my case?
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition, WipeTransition, NoTransition, SlideTransition
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivymd.theming import ThemeManager
import re
class NavTray1(BoxLayout):
pass
class SurveyHeader(GridLayout):
pass
class SubjectsLayout(GridLayout):
pass
class MainScreen(Screen):
pass
class BeginScreen(Screen):
pass
class QuestionsScreen1(Screen):
def insert_data_A(self, *args):
if args[1] == True:
pass
def insert_data_B(self, *args):
self.question_text1 = MDApp.get_running_app().root.current
if args[1] == True:
pass
class MyScreenManager(ScreenManager):
# Create new page from 1 to 5.
def new_page(self):
if self.current == 'begin':
s = QuestionsScreen1(name='Question 1')
if "Question 1" in self.screen_names:
self.current = 'Question 1'
else:
self.add_widget(s)
self.current = 'Question 1'
elif self.current =='Question 5':
pass
else:
current_page_number = int(re.search(r'\d+', self.current).group(0))
s = QuestionsScreen1(name='Question {}'.format(str(int(current_page_number +1))))
if "Question {}".format(str(int(current_page_number +1))) in self.screen_names:
self.current = 'Question {}'.format(str(int(current_page_number +1)))
else:
self.add_widget(s)
self.current = 'Question {}'.format(str(int(current_page_number + 1)))
# Switch screens according to number.
def switch_pages(self, instance):
question_button = StringProperty()
self.question_button = instance.text
s = QuestionsScreen1(name='Question {}'.format(self.question_button))
if 'Question {}'.format(self.question_button) in self.screen_names:
self.current = 'Question {}'.format(self.question_button)
else:
self.add_widget(s)
self.current = 'Question {}'.format(self.question_button)
# Switch screens between 1 to 5.
def back_page(self):
current_page = StringProperty()
if self.current == 'Question 1':
pass
else:
current_page_number = int(re.search(r'\d+', self.current).group(0))
s = QuestionsScreen1(name='Question {}'.format(str(int(current_page_number -1))))
if "Question {}".format(str(int(current_page_number -1))) in self.screen_names:
self.current = 'Question {}'.format(str(int(current_page_number - 1)))
else:
self.add_widget(s)
self.current = 'Question {}'.format(str(int(current_page_number - 1)))
main_widget_kv = ('''
#: import ScrollEffect kivy.effects.scroll.ScrollEffect
MyScreenManager:
BeginScreen:
<BeginScreen>:
begin_button:begin_button
name: "begin"
canvas.before:
Color:
rgb: .1, .1, .1
FloatLayout:
id: begin_layout
Button:
id: begin_button
text: 'Begin'
font_size: 24
on_press: app.root.new_page()
size_hint: (.4,.25)
pos_hint: {"center_x":.5, "center_y":.2}
color: [0,0,0,1]
<NavTray1>:
cols: 3
padding: '5dp'
spacing: '5dp'
canvas.before:
Color:
rgb: .1, .1, .1
Rectangle:
size: self.size
pos: self.pos
MDRaisedButton:
size_hint_x: None
color: [0.4, 0.4, 0.4, 1]
font_style: 'Body1'
height: dp(80)
text: 'Back'
on_release : app.root.back_page()
BoxLayout:
size_hint_x: 0.4
orientation: 'vertical'
Label:
font_style: 'Body1'
MDRaisedButton:
size_hint_x: None
color: [6/255, 114/255, 0, 1]
height: dp(80)
text: "Next"
font_style: 'Body1'
background_color: [28/138, 1, 35/138, 0.5]
on_release : app.root.new_page()
<QuestionsScreen1>:
BoxLayout:
orientation: 'vertical'
size: root.size
pos: root.pos
SurveyHeader:
size_hint: (1.0, None)
height: '90dp'
id: header
rows: 2
Button:
text: "1"
background_color: [0,255,255,1]
on_release: app.root.switch_pages(self)
Button:
text: "2"
background_color: [0,255,255,1]
on_release: app.root.switch_pages(self)
Button:
text: "3"
background_color: [0,255,255,1]
on_release: app.root.switch_pages(self)
Button:
text: "4"
background_color: [0,255,255,1]
on_release: app.root.switch_pages(self)
Button:
text: "5"
background_color: [0,255,255,1]
on_release: app.root.switch_pages(self)
ScrollView:
size_hint: (1.0, None)
height: root.height - header.height - navtray.height
SubjectsLayout:
cols: 1
Label:
size_hint_y : 0.25
text: app.root.current
text_size: self.size
valign: 'middle'
halign: 'center'
GridLayout:
cols: 2
rows: 2
size_hint_y : 0.75
Label:
text: 'a'
font_size: "20dp"
size_hint_x : 0.8
CheckBox:
group: 'answer_group'
size_hint_x : 0.2
on_active: root.insert_data_A(*args)
Label:
text: 'b'
font_size: "20dp"
size_hint_x : 0.8
CheckBox:
group: 'answer_group'
size_hint_x : 0.2
on_active: root.insert_data_B(*args)
NavTray1:
id: navtray
size_hint: (1.0, None)
height: '90dp'
''')
class TestApp(MDApp):
def __init__(self,**kwargs):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Red"
super().__init__(**kwargs)
def build(self):
main_widget = Builder.load_string(main_widget_kv)
return main_widget
if __name__ == '__main__':
TestApp().run()
I have created a simple login, registration, and menu screen that utilize buttons and TextInputs. When i load the app up, the buttons and TextInputs have normal textures, however when i interact with any of the buttons or TextInputs, the textures glitch for all the buttons and TextInputs in the app.
HandwritingRecognition.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
import DatabaseManagement
DatabaseManagement.Create()
USER = ''
class Login_Screen(Screen):
def Login(self):
global USER
USER = self.ids.Username.text
Found = DatabaseManagement.Find_User(self)
if Found:
print("Direct Entry")
self.manager.current = "Login_Successful"
else:
print("Wrong Password")
self.manager.current = "Login_Failed"
def registration(self):
self.manager.current = "Registration_Screen"
class Login_Successful(Screen):
def ChangePassword(self):
self.manager.current = "Change_Password"
def DeleteAccount(self):
global USER
DatabaseManagement.Delete_User(USER)
self.manager.current = "Login_Screen"
def MainScreen(self):
self.manager.current = "Login_Screen"
class Change_Password(Screen):
pass
class LoginConfirmationScreen(Screen):
pass
class Registration_Screen(Screen):
def MainScreen(self):
DatabaseManagement.Data_Entry(self)
self.manager.current = "Login_Screen"
class Login_Failed(Screen):
def MainScreen(self):
self.manager.current = "Login_Screen"
class RootWidget(ScreenManager):
pass
class MainApp(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
MainApp().run()
MainApp.kv
<RootWidget>:
id: Main
Login_Screen:
id: login
name: "Login_Screen"
Change_Password:
id: ChangePass
name: 'Change_Password'
Login_Failed:
id: Failed
name: "Login_Failed"
Login_Successful:
id: Success
name: 'Login_Successful'
Registration_Screen:
id: register
name: 'Registration_Screen'
<Login_Screen>:
GridLayout:
rows:3
cols:2
Label:
text: "Username:"
font_size: 20
TextInput:
id: Username
multiline: False
hint_text: 'Enter your Username'
Label:
text: "Password"
font_size: 20
TextInput:
id: Passwrd
multiline: False
hint_text: 'Enter your Password'
password: True
Button:
text: "Register"
background_color: (1,0,0,1)
on_press: root.registration()
Button:
text: "Sign In"
on_press: root.Login()
<Registration_Screen>:
GridLayout:
rows:4
cols:2
Label:
text: 'First Name:'
font_size: 20
TextInput:
id: FirstName
multiline: False
hint_text: 'Enter your First Name'
Label:
text: 'Surname'
font_size: 20
TextInput:
id: Surname
multiline: False
hint_text: 'Enter your Surname'
Label:
text: 'Password'
font_size: 20
TextInput:
id: Passwrd
multiline: False
hint_text: 'Enter your Password'
password: False
Button:
text: "Create Account"
on_press: root.MainScreen()
<Change_Password>
FloatLayout:
Label:
text: 'Change Password'
pos_hint: {"center_x":0.5, "y":0.75}
font_size: '25sp'
size_hint: 0.5,0.25
Label:
text:'Old Password:'
pos_hint: {"x":0.2, "y":0.6}
font_size: '25sp'
size_hint: 0.3,0.1
TextInput:
pos_hint: {"x": 0.5,"y": 0.6}
size_hint: 0.3,0.1
id: OldPass
multiline: False
password: True
<Login_Successful>:
FloatLayout:
Label:
text: 'Main Menu'
pos_hint: {"center_x":0.5, "y":0.75}
font_size: '25sp'
size_hint: 0.5,0.25
Button:
text: 'Handwriting Recognition'
pos_hint: {"center_x":0.5, "y":0.5}
size_hint: 0.44,0.2
Button:
text: 'Change Password'
pos_hint: {"center_x":0.38, "y":0.27}
size_hint: 0.2,0.2
on_press: root.ChangePassword()
Button:
text: 'Delete Account'
pos_hint: {"center_x":0.38, "y":0.05}
size_hint: 0.2,0.2
on_press: root.DeleteAccount()
Button:
text: 'Log Out'
pos_hint: {"center_x":0.62, "y":0.05}
size_hint: 0.2,0.2
on_press: root.MainScreen()
<Login_Failed>:
BoxLayout:
orientation: "vertical"
Label:
text: "Login Failed"
Button:
text: "Try again"
on_press: root.MainScreen()
DatabaseManagement.py
import sqlite3
conn = sqlite3.connect('HandwritingRecognition.db')
c = conn.cursor()
def Create():
c.execute('CREATE TABLE IF NOT EXISTS Users(FirstName TEXT, Surname TEXT, Username TEXT, Passwrd TEXT)')
def Data_Entry(self):
FirstName = self.ids.FirstName.text
Surname = self.ids.Surname.text
Username = FirstName+Surname
Passwrd = self.ids.Passwrd.text
c.execute("INSERT INTO Users (FirstName,Surname,Username,Passwrd) VALUES(?,?,?,?)",(FirstName,Surname,Username,Passwrd))
conn.commit()
def Find_User(self):
finduser = ('SELECT * FROM Users WHERE Username = ? AND Passwrd = ?')
c.execute(finduser,[(self.ids.Username.text),(self.ids.Passwrd.text)])
data = c.fetchall()
if data:
return True
else:
return False
def Delete_User(USER):
c.execute("DELETE FROM Users WHERE Username = ?",(USER,))
conn.commit()
Here is the screenshot of the application as it is loaded before clicking anything:
Application On Loadup
https://i.stack.imgur.com/cJi27.png
Here is the screenshot after i interact with a TextInput box:
Application after Interaction
https://i.stack.imgur.com/HwZaz.png
I have edited the MainApp.kv to only use FloatLayouts, but i am still getting the same glitch.
<RootWidget>:
id: Main
Login_Screen:
id: login
name: "Login_Screen"
Change_Password:
id: ChangePass
name: 'Change_Password'
Login_Failed:
id: Failed
name: "Login_Failed"
Login_Successful:
id: Success
name: 'Login_Successful'
Registration_Screen:
id: register
name: 'Registration_Screen'
<Login_Screen>:
FloatLayout:
Label:
text: "Login"
font_size: '30sp'
pos_hint: {"center_x":0.5,"y":0.8}
size_hint: 0.4,0.3
Label:
text: "Username:"
font_size: '20sp'
pos_hint: {"center_x": 0.25, "y":0.6}
size_hint: 0.4, 0.25
TextInput:
id: Username
multiline: False
pos_hint: {"center_x": 0.75, "y":0.6}
size_hint: 0.45, 0.15
hint_text: 'Enter your Username'
Label:
text: "Password"
font_size: '20sp'
pos_hint: {"center_x": 0.25, "y":0.3}
size_hint: 0.4, 0.15
TextInput:
id: Passwrd
multiline: False
pos_hint: {"center_x": 0.75, "y":0.3}
size_hint: 0.45, 0.15
hint_text: 'Enter your Password'
password: True
Button:
text: "Register"
pos_hint: {"center_x": 0.25, "y":0}
size_hint: 0.4, 0.15
#background_color: (1,0,0,1)
on_press: root.registration()
Button:
pos_hint: {"center_x": 0.75, "y":0}
size_hint: 0.4, 0.15
text: "Sign In"
on_press: root.Login()
<Registration_Screen>:
FloatLayout:
Label:
text: 'Create an Account'
font_size: '20sp'
pos_hint: {"center_x": 0.5, "y": 0.8}
size_hint: 0.4,0.2
Label:
text: 'First Name:'
font_size: '20sp'
pos_hint: {"center_x": 0.25, "y": 0.6}
size_hint: 0.2, 0.15
TextInput:
id: FirstName
multiline: False
pos_hint: {"center_x": 0.6, "y": 0.6}
size_hint: 0.4, 0.15
hint_text: 'Enter your First Name'
Label:
text: 'Surname'
font_size: '20sp'
pos_hint: {"center_x": 0.25, "y": 0.45}
size_hint: 0.2, 0.15
TextInput:
id: Surname
multiline: False
hint_text: 'Enter your Surname'
pos_hint: {"center_x": 0.6, "y": 0.45}
size_hint: 0.4, 0.15
Label:
text: 'Password'
font_size: '20sp'
pos_hint: {"center_x": 0.25, "y": 0.3}
size_hint: 0.2, 0.15
TextInput:
id: Passwrd
multiline: False
pos_hint: {"center_x": 0.6, "y": 0.3}
size_hint: 0.4, 0.15
hint_text: 'Enter your Password'
password: True
Label:
text: 'Confirm Password'
font_size: '20sp'
pos_hint: {"center_x": 0.25,"y": 0.15}
size_hint: 0.2, 0.15
TextInput:
id: PasswrdConfirm
multiline: False
pos_hint: {"center_x": 0.6, "y": 0.15}
size_hint: 0.4,0.15
hint_text: "Please confirm password"
password: True
Button:
text: "Create Account"
pos_hint: {"center_x": 0.5, "y": 0}
size_hint: 0.6, 0.15
on_press: root.MainScreen()
<Change_Password>
FloatLayout:
Label:
text: 'Change Password'
pos_hint: {"center_x":0.5, "y":0.75}
font_size: '25sp'
size_hint: 0.5,0.25
Label:
text:'Old Password:'
pos_hint: {"x":0.2, "y":0.6}
font_size: '25sp'
size_hint: 0.3,0.1
TextInput:
pos_hint: {"x": 0.5,"y": 0.6}
size_hint: 0.3,0.1
id: OldPass
multiline: False
password: True
<Login_Successful>:
FloatLayout:
Label:
text: 'Main Menu'
pos_hint: {"center_x":0.5, "y":0.75}
font_size: '25sp'
size_hint: 0.5,0.25
Button:
text: 'Handwriting Recognition'
pos_hint: {"center_x":0.5, "y":0.5}
size_hint: 0.44,0.2
Button:
text: 'Change Password'
pos_hint: {"center_x":0.38, "y":0.27}
size_hint: 0.2,0.2
on_press: root.ChangePassword()
Button:
text: 'Delete Account'
pos_hint: {"center_x":0.38, "y":0.05}
size_hint: 0.2,0.2
on_press: root.DeleteAccount()
Button:
text: 'Log Out'
pos_hint: {"center_x":0.62, "y":0.05}
size_hint: 0.2,0.2
on_press: root.MainScreen()
<Login_Failed>:
FloatLayout:
Label:
text: "Login Failed"
pos_hint: {"center_x": 0.5, "y": 0.75}
size_hint: 0.5,0.25
Button:
text: "Try again"
pos_hint: {"center_x":0.5, "y": 0.05}
size_hint: 0.44, 0.2
on_press: root.MainScreen()
The Screen Widget is a RelativeLayout SubClass. It tends to run into a lot of problems. I'd suggest subclassing all Screens to a FloatLayout first:
<Login_Screen>:
FloatLayout:
GridLayout:
rows:3
cols:2
This typically fixes the most unpredictability that comes with screens.