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.
Related
I'm trying to add in a helper text in Kivy Md which pops up if an invalid password is entered. However the helper text that I use is quite long and therefore doesn't fit. Does anyone know how I can move it or make it fit somehow. Below is an image of my issue:
Below is the relevant section of code:
def AddToRecord(self, email, passw, name, cpass):
email.error = False
passw.error = False
name.error = False
cpass.error = False
NewEmail = email.text
NewName = name.text
NewPassword = passw.text
ConfirmPassword = cpass.text
if len(NewName) and len(NewEmail) and len(NewPassword) and len(ConfirmPassword)> 0:
if (len(NewPassword)>8 and any(char in (set(string.punctuation)) for char in (NewPassword)) and
any(char in (set(string.punctuation)) for char in (NewPassword)) and
any(char in (set(string.ascii_uppercase)) for char in (NewPassword)) and
any(char in (set(string.ascii_lowercase)) for char in (NewPassword)) and
any(char in (set(string.digits)) for char in (NewPassword))):
if NewPassword == ConfirmPassword:
# Connect to or create a new database
conn = sqlite3.connect('UserRecords.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 (name TEXT, email TEXT, password TEXT)''')
# Insert the user's information into the table
cursor.execute("INSERT INTO users (name, email, password) VALUES (?, ?, ?)", (NewName, NewEmail, NewPassword))
# Committing the changes and closing the connection to the database file
conn.commit()
conn.close()
else:
cpass.helper_text = "The passwords you have entered do not match"
cpass.error = True
else:
passw.helper_text = """Your password needs to be a minium of 8 characters and must
contain a number, lowercase letter, upper case letter and special character (#!#$, ETC)"""
passw.error = True
else:
if len(NewName) <1 and len(NewEmail) >0:
name.error = True
elif len(NewPassword) <1 and len(NewEmail) >0:
passw.helper_text = "This is a required feild"
passw.error = True
elif len(ConfirmPassword) <1 and len(NewEmail) >0:
cpass.helper_text = "This is required field"
cpass.error = True
Below is the relevant section of KV file:
<SignupScreen>:
ScrollView:
FloatLayout:
size_hint: (1, 1.3)
MDIconButton:
icon: "keyboard-backspace"
pos_hint: {"center_x": 0.35, "center_y": 0.97}
on_release:
root.manager.current = "menu"
Image:
source: "Images/RegisterImage.png"
size_hint_x: 0.4
size_hint_y: 0.75
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.75}
MDLabel:
text: "Sign up"
halign: "center"
pos_hint: {"center_x": 0.387, "center_y": 0.54}
font_size: 30
font_style: "H5"
EmailField:
id: email_widget
hint_text: "Email"
pos_hint: {"center_x": 0.5, "center_y": 0.48}
size_hint_x: None
width: "250dp"
NameField:
id: name_widget
hint_text: "Name"
pos_hint: {"center_x": 0.5, "center_y": 0.39}
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.3}
ConfirmPasswordField:
id: cpass_widget
size_hint_x: None
width: "250dp"
hint_text: "Confirm Password"
pos_hint: {"center_x": 0.5, "center_y": 0.21}
MDFillRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.12}
md_bg_color: 0.3607, 0.3882, 1
size_hint: 0.3, 0
on_release:
app.AddToRecord(root.ids.email_widget.ids.email_field, root.ids.passw_widget.ids.text_field, root.ids.name_widget.ids.name_field,
root.ids.cpass_widget.ids.text_field)
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.08}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.066}
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"
##need to try and fix this helper text, attempt below. It is labeled attempt 1
helper_text: "Your password needs to be a minium of 8 characters and must contain a number, lowercase letter, upper case letter and special character (#!#$, ETC)"
helper_text_mode: "on_error"
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
##this label needs to be fixed or alternative solution's - attempt 1
#MDLabel:
#id: passw_helper
#text: ""
#font_size: 20
#halign: 'left'
#pos_hint: {"center_y": -0.1}
<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"
helper_text: ""
helper_text_mode: "on_error"
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"
helper_text: "Please enter a valid email"
validator: "email"
helper_text_mode: "on_error"
<NameField>:
size_hint_y: None
height: name_field.height
MDTextField:
id: name_field
hint_text: root.hint_text
text: root.text
icon_left: "account"
helper_text: "This is a required field"
helper_text_mode: "on_error"
Any help is much appreicated!
Try adding line breaks in your error string. This way will you can control how the line wraps.
ie.
helper_text: "Your password needs to be a minium of 8 characters \nand must contain a number, lowercase letter, upper case \nletter and special character (#!#$, ETC)"
helper_text_mode: "on_error"
This still won't fit inside the box but at least it will look better.
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
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.
I'm stuck in this problem, I'm using a dialog so that the user can change his password but i cant access the textfield text from the DashboardGerente class...
main.py
class Content(BoxLayout):
old_pass_tf = ObjectProperty()
new_pass_tf = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.app = MDApp.get_running_app()
def show_passnew(self,widget):
if widget.state == "normal":
self.ids.new_pass.password = True
else:
self.ids.new_pass.password = False
def show_passold(self,widget):
if widget.state == "normal":
self.ids.old_pass.password = True
else:
self.ids.old_pass.password = False
class DashboardGerente(Screen):
dialog = None
cont = Content()
def Logout(self):
wm = MDApp.get_running_app().root
wm.current = "Login"
def teste(self):
print(Login.username)
def show_alert_dialog(self):
if not self.dialog:
self.dialog = MDDialog(
title = "Alterar palavra-passe",
text = "Palavra-passe antiga",
content_cls=Content(),
type="custom",
buttons=[
MDFlatButton(
text="Cancelar",
text_color=rgba(0,0,0,1),
on_release = self.cancelar
),
MDFlatButton(
text="Alterar",
text_color = rgba(0,0,0,1),
on_release = self.change_pass
),
],
)
self.dialog.open()
def cancelar(self,obj):
self.dialog.dismiss()
def change_pass(self, obj):
#i want to access the textfield text here
pass
.kv file
<Content>:
orientation: "vertical"
spacing: "12dp"
size_hint_y: None
height: "120dp"
id: content_dialog_change_pass
MDTextField:
id: old_pass
hint_text: "Palavra-passe antiga"
mode: "rectangle"
required: False
color: 1, 0, 1, 1
line_color_focus: 0.5, 0, 1, 1
icon_right: "shield-key"
size_hint: .9, None
password: True
GridLayout:
cols:2
MDCheckbox:
on_press: root.show_passold(self)
size_hint: None, None
height: 5
width: 20
MDLabel:
text: "Mostrar Palavra-passe"
font_size: "13px"
color: 0,0,0,.4
MDTextField:
id: new_pass
hint_text: "Palavra-passe nova"
mode: "rectangle"
required: False
color: 1, 0, 1, 1
line_color_focus: 0.5, 0, 1, 1
icon_right: "shield-key"
size_hint: .9, None
password: True
GridLayout:
cols:2
MDCheckbox:
on_press: root.show_passnew(self)
size_hint: None, None
height: 10
width: 20
MDLabel:
text: "Mostrar Palavra-passe"
font_size: "13px"
color: 0,0,0,.4
<DashboardGerente#FloatLayout>:
name: "DashboardGerente"
MDBottomNavigation:
panel_color: get_color_from_hex("#c300ff")
text_color: 0,0,0,1
MDBottomNavigationItem: ## Perfil do utilizador
name: 'Profile'
text: 'Perfil'
icon: 'account'
badge_icon: "numeric-10"
MDCard:
border_radius: 20
radius: [15]
size_hint:None, None
size: 300, 400
pos_hint: {"center_x": 0.5, "center_y": 0.5}
elevation: 10
orientation: "vertical"
AnchorLayout:
anchor_x: "left"
anchor_y: "top"
MDIconButton:
id:logout
text_color: 0,0,0,1
on_release: root.Logout(), root.teste()
icon: "account-arrow-left"
GridLayout:
cols: 2
padding: 40,0,0,0
MDLabel:
text: "ID: "
MDLabel:
text: "5000"
MDLabel:
text: "Nome: "
MDLabel:
text: "nome"
MDLabel:
text: "Cargo: "
MDLabel:
text: "cargo"
MDLabel:
text: "Salário: "
MDLabel:
text: "1000"
MDLabel:
text: "Secção: "
MDLabel:
text: "Frutaria"
MDRaisedButton:
text: "Mudar palavra-passe"
md_bg_color: 0.5, 0, 1, 1
on_press: root.teste()
pos_hint: {"center_x": 0.5, "center_y": 0.5}
on_release: root.show_alert_dialog()
MDBottomNavigationItem:
name: 'Providers'
text: 'Fornecedores'
icon: 'truck'
MDLabel:
text: 'Mail'
halign: 'center'
MDBottomNavigationItem:
name: 'Products'
text: 'Produtos'
icon: 'shopping'
badge_icon: "numeric-10"
MDLabel:
text: 'Mail'
halign: 'center'
MDBottomNavigationItem:
name: 'Employes'
text: 'Empregados'
icon: 'account-multiple'
badge_icon: "numeric-10"
MDRaisedButton:
text: "Adicionar funcionários"
md_bg_color: 0.5, 0, 1, 1
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDBottomNavigationItem:
name: 'Sections'
text: 'Secções'
icon: 'storefront'
badge_icon: "numeric-10"
MDLabel:
text: 'Mail'
halign: 'center'
This are my project files that matter for now, how can i get the .text value from the old_pass textfield in the DashboardGerente class?
I would suggest as follows,
Create a property, say, user_input = StringProperty("") in your App's subclass. then in kv lang of Content class,
MDTextField:
id: old_pass
on_text: app.user_input = self.text
Now use this in any method of DashboardGerente as MDApp.get_running_app().user_input
I am trying to restructure the kivymd project file but I am not able to place the navigation bar at the place at which it is normally. I cannot see why this is happening (see pictures and code below).
This is how it looks like
and this is how it should look like
I am using the three files app.py, app.kv and labels.py (for injecting labels from a *.py file).
# app.kv
# -*- coding: utf-8 -*-
import os
import kivy.app
from kivy.lang import Builder
from application.kivymd.list import BaseListItem
from application.kivymd.material_resources import DEVICE_TYPE
from application.kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerHeaderBase
from application.kivymd.theming import ThemeManager
# User defined imports
from kivy.core.window import Window
Window.fullscreen = "auto"
class HackedDemoNavDrawer(MDNavigationDrawer):
# DO NOT USE
def add_widget(self, widget, index=0):
if issubclass(widget.__class__, BaseListItem):
self._list.add_widget(widget, index)
if len(self._list.children) == 1:
widget._active = True
self.active_item = widget
# widget.bind(on_release=lambda x: self.panel.toggle_state())
widget.bind(on_release=lambda x: x._set_active(True, list=self))
elif issubclass(widget.__class__, NavigationDrawerHeaderBase):
self._header_container.add_widget(widget)
else:
super(MDNavigationDrawer, self).add_widget(widget, index)
class MainApp(kivy.app.App):
theme_cls = ThemeManager()
title = "Application"
def build(self):
main_widget = Builder.load_file(
os.path.join(os.path.dirname(__file__), "./app.kv")
)
# self.theme_cls.theme_style = 'Dark'
main_widget.ids.text_field_error.bind(
on_text_validate=self.set_error_message,
on_focus=self.set_error_message)
self.bottom_navigation_remove_mobile(main_widget)
return main_widget
def bottom_navigation_remove_mobile(self, widget):
# Removes some items from bottom-navigation demo when on mobile
if DEVICE_TYPE == 'mobile':
widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_2)
if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet':
widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_1)
def set_error_message(self, *args):
if len(self.root.ids.text_field_error.text) == 2:
self.root.ids.text_field_error.error = True
else:
self.root.ids.text_field_error.error = False
def on_pause(self):
return True
def on_stop(self):
pass
if __name__ == '__main__':
MainApp().run()
This is the app.kv file which is injected into the app.py file
# app.kv
#:import Toolbar application.kivymd.toolbar.Toolbar
#:import MDNavigationDrawer application.kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout application.kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider application.kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar application.kivymd.navigationdrawer.NavigationDrawerToolbar
#:import NavigationDrawerSubheader application.kivymd.navigationdrawer.NavigationDrawerSubheader
#:import MDCheckbox application.kivymd.selectioncontrols.MDCheckbox
#:import MDSwitch application.kivymd.selectioncontrols.MDSwitch
#:import MDTextField application.kivymd.textfields.MDTextField
#:import MDThemePicker application.kivymd.theme_picker.MDThemePicker
#:import labels application.labels
NavigationLayout:
id: nav_layout
MDNavigationDrawer:
id: nav_drawer
NavigationDrawerToolbar:
title: labels.NAVIGATION
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.DASHBOARD
on_release: app.root.ids.scr_mngr.current = 'dashboard'
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.SYSTEM_INSPECTOR
on_release: app.root.ids.scr_mngr.current = 'system_inspector'
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.SYSTEM_PARAMETERS
on_release: app.root.ids.scr_mngr.current = 'system_parameters'
BoxLayout:
orientation: 'vertical'
halign: "center"
Toolbar:
id: toolbar
title: labels.APPLICATION_NAME
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
background_hue: '500'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
#right_action_items: [['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
ScreenManager:
id: scr_mngr
Screen:
name: 'dashboard'
MDLabel:
font_style: 'Body1'
theme_text_color: 'Primary'
text: "This is the dashboard!"
size_hint_x:None
width: '250dp'
halign: "center"
pos_hint: {"center_x": 0.50, "center_y": 0.75}
MDCheckbox:
id: grp_chkbox_1
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.25, 'center_y': 0.5}
MDCheckbox:
id: grp_chkbox_2
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': 0.75, 'center_y': 0.5}
_active: False
Screen:
name: 'system_inspector'
MDLabel:
font_style: 'Body1'
theme_text_color: 'Primary'
text: "This is the system_inspector page!"
size_hint_x:None
width: '250dp'
halign: "center"
pos_hint: {"center_x": 0.50, "center_y": 0.75}
MDCheckbox:
id: grp_chkbox_1
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.25, 'center_y': 0.5}
MDCheckbox:
id: grp_chkbox_2
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': 0.75, 'center_y': 0.5}
_active: False
Screen:
name: 'system_parameters'
BoxLayout:
orientation: "horizontal"
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
input_filter: "float"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
input_filter: "int"
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
Screen:
name: 'textfields'
ScrollView:
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
MDTextField:
hint_text: "Persistent helper text"
helper_text: "Text is always here"
helper_text_mode: "persistent"
MDTextField:
id: text_field_error
hint_text: "Helper text on error (Hit Enter with two characters here)"
helper_text: "Two is my least favorite number"
helper_text_mode: "on_error"
MDTextField:
hint_text: "Max text length = 10"
max_text_length: 10
MDTextField:
hint_text: "required = True"
required: True
helper_text_mode: "on_error"
MDTextField:
multiline: True
hint_text: "Multi-line text"
helper_text: "Messages are also supported here"
helper_text_mode: "persistent"
MDTextField:
hint_text: "color_mode = \'accent\'"
color_mode: 'accent'
MDTextField:
hint_text: "color_mode = \'custom\'"
color_mode: 'custom'
helper_text_mode: "on_focus"
helper_text: "Color is defined by \'line_color_focus\' property"
line_color_focus: self.theme_cls.opposite_bg_normal # This is the color used by the textfield
MDTextField:
hint_text: "disabled = True"
disabled: True
Screen:
name: 'nav_drawer'
HackedDemoNavDrawer:
# NavigationDrawerToolbar:
# title: "Navigation Drawer Widgets"
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: "Badge text ---->"
badge_text: "99+"
NavigationDrawerIconButton:
active_color_type: 'accent'
text: "Accent active color"
NavigationDrawerIconButton:
active_color_type: 'custom'
text: "Custom active color"
active_color: [1, 0, 1, 1]
NavigationDrawerIconButton:
use_active: False
text: "Use active = False"
NavigationDrawerIconButton:
text: "Different icon"
icon: 'alarm'
NavigationDrawerDivider:
NavigationDrawerSubheader:
text: "NavigationDrawerSubheader"
NavigationDrawerIconButton:
text: "NavigationDrawerDivider \/"
NavigationDrawerDivider:
Here is the labels.py file for injecting the labels into the kv file.
# labels.py
APPLICATION_NAME = "Application"
NAVIGATION = "Navigation"
DASHBOARD = "Dashboard"
SYSTEM_INSPECTOR = "System Inspector"
SYSTEM_PARAMETERS = "System Parameters"
Solution
You might have a kv file with a name, main.kv
With KivyMD installed on my machine, and some minor changes, the KivyMD App ran fine.
Example
app.py
# app.py
# -*- coding: utf-8 -*-
import os
from kivy.app import App
from kivy.lang import Builder
from kivymd.list import BaseListItem
from kivymd.material_resources import DEVICE_TYPE
from kivymd.navigationdrawer import MDNavigationDrawer, NavigationDrawerHeaderBase
from kivymd.theming import ThemeManager
# User defined imports
from kivy.core.window import Window
# Window.fullscreen = "auto"
class HackedDemoNavDrawer(MDNavigationDrawer):
# DO NOT USE
def add_widget(self, widget, index=0):
if issubclass(widget.__class__, BaseListItem):
self._list.add_widget(widget, index)
if len(self._list.children) == 1:
widget._active = True
self.active_item = widget
# widget.bind(on_release=lambda x: self.panel.toggle_state())
widget.bind(on_release=lambda x: x._set_active(True, list=self))
elif issubclass(widget.__class__, NavigationDrawerHeaderBase):
self._header_container.add_widget(widget)
else:
super(MDNavigationDrawer, self).add_widget(widget, index)
class MainApp(App):
theme_cls = ThemeManager()
title = "Application"
def build(self):
main_widget = Builder.load_file(
os.path.join(os.path.dirname(__file__), "./app.kv")
)
# self.theme_cls.theme_style = 'Dark'
main_widget.ids.text_field_error.bind(
on_text_validate=self.set_error_message,
on_focus=self.set_error_message)
self.bottom_navigation_remove_mobile(main_widget)
return main_widget
def bottom_navigation_remove_mobile(self, widget):
# Removes some items from bottom-navigation demo when on mobile
if DEVICE_TYPE == 'mobile':
widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_2)
if DEVICE_TYPE == 'mobile' or DEVICE_TYPE == 'tablet':
widget.ids.bottom_navigation_demo.remove_widget(widget.ids.bottom_navigation_desktop_1)
def set_error_message(self, *args):
if len(self.root.ids.text_field_error.text) == 2:
self.root.ids.text_field_error.error = True
else:
self.root.ids.text_field_error.error = False
def on_pause(self):
return True
def on_stop(self):
pass
if __name__ == '__main__':
MainApp().run()
labels.py
# labels.py
APPLICATION_NAME = "Application"
NAVIGATION = "Navigation"
DASHBOARD = "Dashboard"
SYSTEM_INSPECTOR = "System Inspector"
SYSTEM_PARAMETERS = "System Parameters"
app.kv
# app.kv
#:kivy 1.11.0
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerDivider kivymd.navigationdrawer.NavigationDrawerDivider
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar
#:import NavigationDrawerSubheader kivymd.navigationdrawer.NavigationDrawerSubheader
#:import MDCheckbox kivymd.selectioncontrols.MDCheckbox
#:import MDSwitch kivymd.selectioncontrols.MDSwitch
#:import MDTextField kivymd.textfields.MDTextField
#:import MDThemePicker kivymd.theme_picker.MDThemePicker
#:import labels labels
NavigationLayout:
id: nav_layout
MDNavigationDrawer:
id: nav_drawer
NavigationDrawerToolbar:
title: labels.NAVIGATION
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.DASHBOARD
on_release: app.root.ids.scr_mngr.current = 'dashboard'
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.SYSTEM_INSPECTOR
on_release: app.root.ids.scr_mngr.current = 'system_inspector'
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: labels.SYSTEM_PARAMETERS
on_release: app.root.ids.scr_mngr.current = 'system_parameters'
BoxLayout:
orientation: 'vertical'
halign: "center"
Toolbar:
id: toolbar
title: labels.APPLICATION_NAME
md_bg_color: app.theme_cls.primary_color
background_palette: 'Primary'
background_hue: '500'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer()]]
#right_action_items: [['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
ScreenManager:
id: scr_mngr
Screen:
name: 'dashboard'
MDLabel:
font_style: 'Body1'
theme_text_color: 'Primary'
text: "This is the dashboard!"
size_hint_x:None
width: '250dp'
halign: "center"
pos_hint: {"center_x": 0.50, "center_y": 0.75}
MDCheckbox:
id: grp_chkbox_1
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.25, 'center_y': 0.5}
MDCheckbox:
id: grp_chkbox_2
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': 0.75, 'center_y': 0.5}
_active: False
Screen:
name: 'system_inspector'
MDLabel:
font_style: 'Body1'
theme_text_color: 'Primary'
text: "This is the system_inspector page!"
size_hint_x:None
width: '250dp'
halign: "center"
pos_hint: {"center_x": 0.50, "center_y": 0.75}
MDCheckbox:
id: grp_chkbox_1
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.25, 'center_y': 0.5}
MDCheckbox:
id: grp_chkbox_2
group: 'test'
size_hint: None, None
size: dp(48), dp(48)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
MDSwitch:
size_hint: None, None
size: dp(36), dp(48)
pos_hint: {'center_x': 0.75, 'center_y': 0.5}
_active: False
Screen:
name: 'system_parameters'
BoxLayout:
orientation: "horizontal"
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
input_filter: "float"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
input_filter: "int"
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
Screen:
name: 'textfields'
ScrollView:
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
padding: dp(48)
spacing: 10
MDTextField:
hint_text: "No helper text"
MDTextField:
hint_text: "Helper text on focus"
helper_text: "This will disappear when you click off"
helper_text_mode: "on_focus"
MDTextField:
hint_text: "Persistent helper text"
helper_text: "Text is always here"
helper_text_mode: "persistent"
MDTextField:
id: text_field_error
hint_text: "Helper text on error (Hit Enter with two characters here)"
helper_text: "Two is my least favorite number"
helper_text_mode: "on_error"
MDTextField:
hint_text: "Max text length = 10"
max_text_length: 10
MDTextField:
hint_text: "required = True"
required: True
helper_text_mode: "on_error"
MDTextField:
multiline: True
hint_text: "Multi-line text"
helper_text: "Messages are also supported here"
helper_text_mode: "persistent"
MDTextField:
hint_text: "color_mode = \'accent\'"
color_mode: 'accent'
MDTextField:
hint_text: "color_mode = \'custom\'"
color_mode: 'custom'
helper_text_mode: "on_focus"
helper_text: "Color is defined by \'line_color_focus\' property"
line_color_focus: self.theme_cls.opposite_bg_normal # This is the color used by the textfield
MDTextField:
hint_text: "disabled = True"
disabled: True
Screen:
name: 'nav_drawer'
HackedDemoNavDrawer:
# NavigationDrawerToolbar:
# title: "Navigation Drawer Widgets"
NavigationDrawerIconButton:
icon: 'checkbox-blank-circle'
text: "Badge text ---->"
badge_text: "99+"
NavigationDrawerIconButton:
active_color_type: 'accent'
text: "Accent active color"
NavigationDrawerIconButton:
active_color_type: 'custom'
text: "Custom active color"
active_color: [1, 0, 1, 1]
NavigationDrawerIconButton:
use_active: False
text: "Use active = False"
NavigationDrawerIconButton:
text: "Different icon"
icon: 'alarm'
NavigationDrawerDivider:
NavigationDrawerSubheader:
text: "NavigationDrawerSubheader"
NavigationDrawerIconButton:
text: "NavigationDrawerDivider \/"
NavigationDrawerDivider:
Output