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.
Related
I'm trying to print user input from MDTextField to a label, but I keep getting "AttributeError: 'super' object has no attribute 'getattr'".
Here's my python file:
'''
class TodoLayout(MDScreen, MDFloatLayout):
pass
class CatLayout(Screen):
pass
class WindowManager(ScreenManager):
pass
class BullyCat(MDApp, App):
def get_data(self):
user_input = (self.root.get_screen("to_do_view").ids.data.text)
self.root.get_screen("to_do_view").ids.label_id.text = user_input
def build(self):
return Builder.load_file("kivyfile.kv")
def add_todo(self):
global screen_manager
screen_manager = ScreenManager()
screen_manager.get_screen("main").todo_list.add_widget(TodoCard())
if __name__ == "__main__":
BullyCat().run()
'''
Here's my .kv file:
'''
WindowManager:
TodoLayout:
CatLayout:
<TodoLayout>:
name: "to_do_view"
MDScreen:
id: 'main'
name: 'main'
MDFloatLayout:
md_bg_color: 0, 1, 0, .1
MDLabel:
text: "MyTasks"
pos_hint: {"center_x": .9, "center_y": .95}
font_size: "35sp"
MDLabel:
id: date
text: ""
pos_hint: {"center_x": .885, "center_y": .89}
font_size: "18sp"
MDIconButton:
icon: "plus"
pos_hint: {"center_x": .92, "center_y": .925}
user_font_size: "30sp"
md_bg_color: 30/255, 1, 30/255, 0.8
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_release: on_release: root.ids.add_input.text = choice(app.my_list)
MDIconButton:
icon: "cat"
pos_hint: {"center_x": .075, "center_y": .925}
user_font_size: "30sp"
md_bg_color: 30/255, 1, 30/255, 0.8
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_release:
app.root.current = "cat_view"
root.manager.transition.direction = "left"
MDTextField:
id: data
hint_text: "Write a task"
pos_hint: {"center_x": .5, "center_y": .1}
size_hint: 0.5, None
MDRectangleFlatButton:
text: 'add'
pos_hint: {"center_x": .8, "center_y": .1}
on_release: app.get_data()
MDLabel:
id: 'label_id'
text: 'Task 1'
pos_hint: {"center_x": .9, "center_y": .8}
font_size: 30
<CatLayout>:
name: 'cat_view'
MDScreen:
id: 'second'
name: 'second'
MDFloatLayout:
md_bg_color: 0, 1, 0, .1
MDIconButton:
icon: "pencil"
pos_hint: {"center_x": .075, "center_y": .925}
user_font_size: "30sp"
md_bg_color: 30/255, 1, 30/255, 0.8
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
on_release:
app.root.current = "to_do_view"
root.manager.transition.direction = "right"
MDTextField:
hint_text: "Persistent helper text"
pos_hint: {"center_x": .5, "center_y": .1}
size_hint: 0.5, None
'''
Ultimately i'm trying to build a to-do app with an animated cat that will bully you verbally into doing your tasks.
I suspect the problem lies within here:
def get_data(self):
user_input = (self.root.get_screen("to_do_view").ids.data.text)
self.root.get_screen("to_do_view").ids.label_id.text = user_input
I am very new to coding and i'm a bit lost here. Thanks a lot!
Ids in your kv should not be enclosed in quotes. Just change:
id: 'label_id'
to:
id: label_id
Hows it going guys. I have been looking for two days now and I cant seem to connect the dots. Please forgive me I am somewhat experienced with python but OOP concepts are still a little unclear. I have seen a couple similar posts but the python is a little over my head.
What I am trying to do is set the temperature (and eventually humidity) in a separate screen (Button called Set Temp). Then have that set temp value from that screen show up on my main screen. I tried to tie the temperature value to a global variable (tep). Then when one would hit main menu button (within the set temp screen) and call a method within the main screen class that would reference that global tep variable. But when I do this nothing happens. I have tired to call it by ID, create a method within the main menu to explicitly update that variable but to no avail and vice versa but nothing seems to work. I tried looking how to refresh the screen but the examples were over my head. If someone could shed some light on this issue that would be awesome.
Thanks for taking the time to read my post!
python file
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.properties import ObjectProperty
from random import randint
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
Window.size = (600,250)
tep = 75
# Window Manager Class
class WindowManager(ScreenManager):
pass
# Main home menu Class
class MyTerrLayout(Screen):
internal_read = ObjectProperty(None)
external_read = ObjectProperty(None)
target_temp = ObjectProperty(None)
target_hum = ObjectProperty(None)
def set_temp(self):
global tep
self.ids._Target_Temp.text = str(tep)
print(str(tep))
# Temprature Screen Class / Window
class TempWindow(Screen):
temp_menu = ObjectProperty(None)
def sub_temp(self):
global tep
tep = tep - 1
self.temp_menu.text = str(tep)
def add_temp(self):
global tep
tep = tep + 1
self.temp_menu.text = str(tep)
def set_temp(self):
MyTerrLayout().set_temp()
# Humidity Class / Window
class HumWindow(Screen):
pass
# Builder Section
kv = Builder.load_file('terrlayoutV1.kv')
class TerrLayout(App):
def build(self):
return kv
if __name__=="__main__":
TerrLayout().run()
Kivy File
#:kivy 1.0.9
WindowManager:
MyTerrLayout:
TempWindow:
HumWindow:
<MyTerrLayout>:
name: "main"
internal_read: internal_reading
external_read: external_reading
target_temp: _Target_Temp
target_hum: _Target_Hum
GridLayout:
cols:2
RelativeLayout:
Label:
id: _internal
text: 'Internal Temp/Humidity'
size_hint: 0.5 , .166
pos_hint: {'x': .25, 'top': 1}
Label:
text: 'Target:'
font_size: 15
size_hint: 0.125 , .166
pos_hint: {'x': 0.1, 'top': 0.834}
Label:
id: _Target_Temp
size_hint: 0.125 , .166
pos_hint: {'x': .25, 'top': 0.834}
Label:
id: _Target_Hum
size_hint: 0.125 , .166
pos_hint: {'x': .38, 'top': 0.834}
Label:
text: 'Current:'
size_hint: 0.125 , .166
pos_hint: {'x': .55, 'top': 0.834}
Label:
id: internal_reading
text: '25C/35%'
size_hint: 0.125 , .166
pos_hint: {'x': .75, 'top': 0.834}
Label:
id: _external
text: 'External Temp/Humidity'
size_hint: 0.5, .166
pos_hint: {'x': .25, 'top': 0.668}
Label:
id: external_reading
size_hint: 0.5, .166
pos_hint: {'x': .25, 'top': 0.502}
Label:
id: _heatbed
text: 'Heatbed Temprature'
size_hint: 0.5, .166
pos_hint: {'x': 0.25, 'top': 0.336}
Label:
id: heatbed_reading
text: '80C'
size_hint: 0.5, .166
pos_hint: {'x': 0.25, 'top': 0.17}
StackLayout:
orientation: 'rl-tb'
spacing: 1.5
Button:
id: _Set_Temp
text: 'Set Temp'
size_hint: [.5, .25]
on_release: app.root.current = "Temp"
Button:
id: _Set_Hum
text: 'Set Humidity'
size_hint: [.5, .25]
on_release: app.root.current = "Hum"
Button:
id: _Set_Fan
text: 'Set Fan Time'
size_hint: [.5, .25]
Button:
id: _Set_Light
text: 'Set Light Time'
size_hint: [.5, .25]
Button:
id: _Tog_Light
text: 'Toggle Light'
size_hint: [.5, .25]
Button:
id: _Tog_Fan
text: 'Toggle Fan'
size_hint: [.5, .25]
Button:
id: _Dis_Mode
text: 'Display Mode'
size_hint: [1, .25]
<TempWindow>:
name: "Temp"
temp_menu: set_tep_menu
GridLayout:
cols: 2
Label:
id: set_tep_menu
size_hint: 1, .5
font_size: 32
StackLayout:
orientation: 'rl-tb'
Button:
text: "Increase Temp"
on_press: root.add_temp()
size_hint: [1, .3]
Button:
text: "Decrease Temp"
on_press: root.sub_temp()
size_hint: [1, .3]
Button:
text: "Main Menu"
on_release: app.root.current = "main"
on_release: root.set_temp() #calling method to set temp
size_hint: [1, .3]
<HumWindow>:
name: "Hum"
Button:
text: "Humidity"
on_release: app.root.current = "main"
Your code:
def set_temp(self):
MyTerrLayout().set_temp()
is creating a new instance of MyTerrLayout and calling set_temp() on that instance. However, that new instance of MyTerrLayout is not part of your GUI, so no changes are visible. To actually change your GUI, you need to call the set_temp() method of the MyTerrLayout instance that is in your GUI. To do that, change the set_temp() method of TempWindow to:
def set_temp(self):
terrLayout = self.manager.get_screen('main')
terrLayout.set_temp()
Is it possible to check if two images are overlapping or colliding in kivy?
I am using ScreenManager, and have a moving image that I am controlling. I want to check if it collides, and when that happens I want its pos to change (-)negatively.
I don't know what code to include. But here is some that is somewhat relevent.
Py Code:
xnum = 0.53
ynum = 0.412
xmovement = 0.0889
ymovement = 0.05
movementt = 0.1
class L1(Screen):
screensize()
def animate_down_button(self, widget, *args):
global ynum
global ymovement
global movementt
ynum -= ymovement
anim = Animation(y_hint=ynum, duration=movementt)
anim.start(widget)
pass
def animate_up_button(self, widget, *args):
global ynum
global ymovement
ynum += ymovement
anim = Animation(y_hint=ynum, duration=movementt)
anim.start(widget)
pass
def animate_right_button(self, widget, *args):
global xnum
global xmovement
xnum += xmovement
anim = Animation(x_hint=xnum, duration=movementt)
anim.start(widget)
pass
def animate_left_button(self, widget, *args):
global xnum
global xmovement
xnum -= xmovement
anim = Animation(x_hint=xnum, duration=movementt)
anim.start(widget)
pass
def play_nav(self):
if nav:
nav.play()
Kv Code:
<L1>:
name: "L1"
canvas:
Rectangle:
source: 'background.jpg'
size: root.width, root.height
Rectangle:
source: 'Mazebg.png'
size: root.width*0.7, root.height*0.6
pos: root.width*0.5 - root.width*0.35, root.height*0.32
Rectangle:
source: 'Maze1.png'
size: root.width*0.7, root.height*0.6
pos: root.width*0.5 - root.width*0.35, root.height*0.32
Rectangle:
source: 'Star.png'
size: root.width*1.5, root.height*0.25
pos: (root.width*-0.125), root.height*0.92
Button:
pos_hint: {"x":0.01, "top":0.995}
size_hint: 0.15, 0.075
background_normal: 'BackArrow.png'
background_down: 'BackArrowPressed.png'
on_release: root.play_nav()
on_release: app.root.current = "GameMenu"
Image:
id: mazeball
source: 'ball.png'
size_hint: 0.07, 0.07
x_hint: 0.53
y_hint: 0.412
pos_hint: {"x": self.x_hint, "top": self.y_hint}
Button:
pos_hint: {"x":0.4, "top":0.17}
size_hint: 0.2, 0.1
background_normal: 'PadDown.png'
background_down: 'PadDownPressed.png'
on_release: root.play_nav()
on_press: root.animate_down_button(mazeball)
Button:
pos_hint: {"x":0.4, "top":0.31}
size_hint: 0.2, 0.1
background_normal: 'PadUp.png'
background_down: 'PadUpPressed.png'
on_release: root.play_nav()
on_press: root.animate_up_button(mazeball)
Button:
pos_hint: {"x":0.525, "top": 0.235}
size_hint: 0.2, 0.1
background_normal: 'PadRight.png'
background_down: 'PadRightPressed.png'
on_release: root.play_nav()
on_press: root.animate_right_button(mazeball)
Button:
pos_hint: {"x":0.275, "top": 0.235}
size_hint: 0.2, 0.1
background_normal: 'PadLeft.png'
background_down: 'PadLeftPressed.png'
on_release: root.play_nav()
on_press: root.animate_left_button(mazeball)
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()
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.