Please I keep getting an attribute error when I try to get the text a user input into an MDTextField, tried everything I could think of, researched and couldn't get anything. Please I need your help.
I try to get the text with this argument of self.root.ids.MyId.text
This is the error I get:
File "C:/Users/user/Documents/KmD/Webma/main_webma.py", line 120, in login
email_addr = self.root.ids.email.text
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
And this is my main.py code
from kivymd.app import MDApp
from kivy.clock import Clock
from kivy.lang import Builder
from home_page_strings import toolbar
import sqlite3
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.picker import MDThemePicker
from kivy.uix.popup import Popup
from kivymd.uix.textfield import MDTextField
# calling of screen classes and addition to the screen_manager
class Friend1(Screen):
pass
class WelcomeScreen(Screen):
def __init__(self, **kwargs):
super(WelcomeScreen, self).__init__(**kwargs)
Clock.schedule_once(self.callNext, 5)
def callNext(self, dt):
self.manager.current = 'account'
class AccountScreen(Screen):
pass
class HomeScreen(Screen):
pass
class RoomScreen(Screen):
pass
class ContactsScreen(Screen):
pass
class CallsScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class FaqScreen(Screen):
pass
class InviteScreen(Screen):
pass
manager = ScreenManager()
manager.add_widget(Friend1(name='friend1'))
manager.add_widget(HomeScreen(name='home'))
manager.add_widget(WelcomeScreen(name='welcome'))
manager.add_widget(RoomScreen(name='room'))
manager.add_widget(ContactsScreen(name='contacts'))
manager.add_widget(CallsScreen(name='calls'))
manager.add_widget(SettingsScreen(name='settings'))
manager.add_widget(FaqScreen(name='faq'))
manager.add_widget(InviteScreen(name='invite'))
manager.add_widget(AccountScreen(name='account'))
# end of call of screen classes and addition to screenmanager
class EMC_WebmaApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# -------------------------- CODE FOR THE DATABASE ---------------------------------- #
conn = sqlite3.connect('webma_database.db')
cursor = conn.cursor()
# cursor.execute('''CREATE TABLE users (
# email text,
# password integer
# )''')
def sign_up(self, cursor):
cursor.execute('INSERT INTO users VALUES('', '')')
conn.commit()
conn.close()
# -------------------------- END OF CODE FOR THE DATABASE ---------------------------------- #
# BUILDER FUNCTION AND SCREEN
def build(self):
screen = Screen()
# theme settings
self.theme_cls.primary_palette = 'DeepPurple'
self.theme_cls.theme_style = 'Dark'
# end of theme declaration
# loaded strings
navigation_bar = Builder.load_string(toolbar)
# end of loaded strings
# addition of loaded strings to screen + return screen
screen.add_widget(navigation_bar)
return screen
# end of addition
# END OF BUILDER FUNCTION
# USER VALIDATION FUNCTION
def login(self):
email_addr = self.root.ids.email.text
if email_addr == str(''):
print('Invalid Email Address')
# END OF USER VALIDATION
def change(self, dt):
self.root.manager.current = 'home'
# App theme manager
def change_theme(self):
picker = MDThemePicker()
picker.open()
# End of app theme manager
# home page search bar
def search_bar(self, dt):
searchbar = Popup(
title='Search',
content=MDTextField(
helper_text='Input values to be searched for',
helper_text_mode='on_focus'
),
auto_dismiss=True,
# size_hint=(None, None),
# size=(400, 98)
size_hint=(0.7, 0.17),
pos_hint={'center_x': 0.5, 'center_y': 0.8}
)
searchbar.open()
# APP RUN
if __name__ == '__main__':
EMC_WebmaApp().run()
# WELL... THIS IS THE END OF EVERYTHING
Then my string code where I try to get my text from
toolbar = '''
ScreenManager:
WelcomeScreen:
HomeScreen:
RoomScreen:
ContactsScreen
CallsScreen:
SettingsScreen:
FaqScreen:
InviteScreen:
AccountScreen:
Friend1:
<WelcomeScreen>:
name: 'welcome'
Image:
source: 'logo.png'
size_hint: 0.4, 0.4
pos_hint: {'center_x': 0.5, 'center_y':0.6}
MDLabel:
text: 'Webma'
halign: 'center'
font_style: 'H3'
color: (1, 1, 1, 1)
pos_hint: {'center_x': 0.5, 'center_y':0.8}
MDLabel:
text: 'Powered by emc_codes'
halign: 'center'
bold: 'True'
italic: True
pos_hint: {'center_x': 0.5, 'center_y':0.1}
<HomeScreen>:
name: 'home'
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
spacing: '8dp'
MDToolbar:
title: 'EMC_Webma'
left_action_items: [['menu', lambda x: navigation.set_state('open')]]
right_action_items: [['card-search', app.search_bar]]
elevation: 10
ScrollView:
MDList:
TwoLineAvatarIconListItem:
text: 'Friend 1'
ImageLeftWidget:
source: 'einstein.jpg'
IconRightWidget:
icon: 'dots-vertical'
MDNavigationDrawer:
id: navigation
BoxLayout:
orientation: 'vertical'
spacing: '8dp'
padding: '8dp'
Image:
source: 'einstein.jpg'
MDLabel:
text: 'Enwerem Melvin Confidence'
font_style: 'Subtitle2'
size_hint_y: None
height: self.texture_size[1]
MDLabel:
text: 'enweremmelvinconfidence#gmail.com'
font_style: 'Caption'
size_hint_y: None
height: self.texture_size[1]
ScrollView:
MDList:
OneLineIconListItem:
text: 'Room'
on_release: root.manager.current = 'room'
IconLeftWidget:
icon: 'theater'
on_release: root.manager.current = 'room'
OneLineIconListItem:
text: 'Contacts'
on_release: root.manager.current = 'contacts'
IconLeftWidget:
icon: 'contacts'
on_release: root.manager.current = 'contacts'
OneLineIconListItem:
text: 'Calls'
on_release: root.manager.current = 'calls'
IconLeftWidget:
icon: 'cellphone-android'
on_release: root.manager.current = 'calls'
OneLineIconListItem:
text: 'Settings'
on_release: root.manager.current = 'settings'
IconLeftWidget:
icon: 'settings'
on_release: root.manager.current = 'settings'
OneLineIconListItem:
text: 'FAQ'
on_release: root.manager.current = 'faq'
IconLeftWidget:
icon: 'frequently-asked-questions'
on_release: root.manager.current = 'faq'
OneLineIconListItem:
text: 'Invite Friends'
on_release: root.manager.current = 'invite'
IconLeftWidget:
icon: 'account-plus'
on_release: root.manager.current = 'invite'
OneLineIconListItem:
text: 'Theme Manager'
on_release:
app.change_theme()
IconLeftWidget:
icon: 'theme-light-dark'
<RoomScreen>:
name: 'room'
MDLabel:
text: 'Welcome to the Room Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<ContactsScreen>:
name: 'contacts'
MDLabel:
text: 'Welcome to the Contacts Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<CallsScreen>:
name: 'calls'
MDLabel:
text: 'Welcome to the Calls Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<SettingsScreen>:
name: 'settings'
MDLabel:
text: 'Welcome to the Settings Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<FaqScreen>:
name: 'faq'
MDLabel:
text: 'Welcome to the Faq Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<InviteScreen>:
name: 'invite'
MDLabel:
text: 'Welcome to the Invite Screen'
halign: 'center'
bold: True
font_size: 50
MDIconButton:
icon: 'keyboard-backspace'
pos_hint: {'center_x': 0.06, 'center_y': 0.96}
on_release: root.manager.current = 'home'
size_hint: None, None
<AccountScreen>:
name: 'account'
BoxLayout:
MDLabel:
text: 'Account Login'
pos_hint: {'center_x': 0.6, 'center_y': 0.9}
color: (1, 1, 1, 1)
font_size: 40
MDTextFieldRound:
id: email
hint_text: 'Email Address'
icon_right: 'email'
icon_right_color: app.theme_cls.primary_color
pos_hint: {'center_x': 0.5, 'center_y': 0.7}
size_hint_x: None
width: 300
MDTextFieldRound:
id: password
hint_text: 'Enter Password'
icon_right: 'lock'
icon_right_color: app.theme_cls.primary_color
password: True
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
size_hint_x: None
width: 300
MDRaisedButton:
text: 'Login'
md_bg_color: app.theme_cls.primary_color
pos_hint: {'center_x': 0.5, 'center_y': 0.2}
on_release: app.login() # root.manager.current = 'home'
<Friend1>
name: 'friend1'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Friend 1'
left_action_items: [['keyboard-backspace', app.change]]
right_action_items: [['phone', lambda x: print('go ahead and make a call')], ['video', lambda x: print('Video')], ['dots-vertical', lambda x: print('dots')]]
MDLabel:
text: 'This is a test screen for our Chat'
halign: 'center'
'''
Please guys I really appreciate the help. Thanks in advance...
The email id only appears in the ids for the AccountScreen. Any id appearing in a kv gets inserted into the ids of the widget that is the root of the rule that contains the id. So, you must access the AccountScreen instance to get to the email id:
# BUILDER FUNCTION AND SCREEN
def build(self):
screen = Screen()
# theme settings
self.theme_cls.primary_palette = 'DeepPurple'
self.theme_cls.theme_style = 'Dark'
# end of theme declaration
# loaded strings
self.navigation_bar = Builder.load_string(toolbar) # save a reference to the loaded ScreenManager
# end of loaded strings
# addition of loaded strings to screen + return screen
screen.add_widget(self.navigation_bar)
return screen
# end of addition
# END OF BUILDER FUNCTION
# USER VALIDATION FUNCTION
def login(self):
# use the saved reference to access the email address
email_addr = self.navigation_bar.get_screen('account').ids.email.text
if email_addr == str(''):
print('Invalid Email Address')
# END OF USER VALIDATION
value = self.root.get_screen('nameofscreen').ids.username.text
print("What you typed is: ", value)
syntax = self.root.get_screen('name').ids.id.text
Related
Im relatively new to Kivy/KivyMD. I cant figure out how to take the values from the username and password text fields and turn them into variable in my python file when the sign up button is pressed.
Currently when the Signup button is clicked it just prints "clicked".
Any help would be greatly appreciated!
Below is my python file:
from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivy.lang import Builder
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition
Builder.load_file('ALevelNEA.kv')
##Below are the classes for my different screens
class SignupScreen(Screen):
pass
class MenuScreen(Screen):
pass
class SigninScreen(Screen):
pass
## Below are the classes for my custom buttons, widgets and text fields
class PasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class EmailField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
#email_field = ObjectProperty(None)
##Below is the code for my main app
class MainApp(MDApp):
def build(self):
sm = ScreenManager(transition= SwapTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SigninScreen(name = 'signin'))
sm.add_widget(SignupScreen(name='signup'))
return sm
def RecordCheck(self):
print("clicked")
def AddToRecord(self):
print("clicked")
if __name__ == '__main__':
MainApp().run()
Below is my KV file:
#Below are my different screens
#Below is the Menu Screen
<MenuScreen>:
Screen:
Image:
source: "Logonb.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.6 }
MDFillRoundFlatButton:
id: SignIn
text: "Sign in with email"
pos_hint: {"center_x": 0.5, "center_y": 0.2}
md_bg_color: 0.3607, 0.3882, 1
size_hint: 0.225, 0
on_release:
root.manager.current = "signin"
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.12}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
on_release:
root.manager.current = "signup"
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.07}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.0525}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
# Below is my sign in Screen
<SigninScreen>:
Screen:
MDIconButton:
icon: "keyboard-backspace"
pos_hint: {"center_x": 0.35, "center_y": 0.95}
on_release:
root.manager.current = "menu"
Image:
source: "LoginImage.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.7 }
MDLabel:
text: "Sign in"
halign: "center"
pos_hint: {"center_x": 0.387, "center_y": 0.45}
font_size: 30
font_style: "H5"
EmailField:
hint_text: "Email ID"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
PasswordField:
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
MDTextButton:
text: "Forgot password?"
font_size: 15
pos_hint: {"center_x": 0.62, "center_y": 0.255}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
MDFillRoundFlatButton:
text: "Sign in"
pos_hint: {"center_x": 0.5, "center_y": 0.2}
md_bg_color: 0.3607, 0.3882, 1
size_hint: 0.225, 0
on_release: app.RecordCheck()
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.15}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.1325}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
#Below is the sign up screen
<SignupScreen>:
Screen:
EmailField:
hint_text: "Email"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
on_text: root.email = self.text
PasswordField:
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
on_text: root.password = self.text
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.12}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
on_release: app.AddToRecord()
#Custom buttons and text fields are located below
<PasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<EmailField>:
size_hint_y: None
height: email_field.height
MDTextField:
id: email_field
hint_text: root.hint_text
text: root.text
icon_left: "email"
Add id attribute both to email and password widgets:
EmailField:
id: email_widget
PasswordField:
id: pass_widget
And you can pass any additional parameters to your method, for example replace:
on_release: app.AddToRecord()
with
on_release: app.AddToRecord(root.ids.email_widget.ids.email_field.text, root.ids.pass_widget.ids.text_field.text)
then change your AddToRecord method definition to:
def AddToRecord(self, email, passw):
print("clicked")
print(f'email: {email}, password: {passw}')
For the email, you can use the get_screen() method of ScreenManager and some ids to access the MDTextField that contains the text. First, add an id to the EmailField:
EmailField:
id: emailfield # added id
hint_text: "Email ID"
pos_hint: {"center_x": 0.5, "center_y": 0.375}
size_hint_x: None
width: "250dp"
Then use that new id and get_screen() to access the MDTextField in your RecordCheck() method:
def RecordCheck(self):
print("clicked")
signinScreen = self.root.get_screen('signin')
email = signinScreen.ids.emailfield.ids.email_field.text
print('email:', email)
Very similar approach can be used to access the password.
I'm relatively new to Kivy/KivyMD. I'm currently trying to figure out how to set up a scroll view for one of my screens. As far as I'm aware in order to use a scroll view I need to use a grid layout. Whenever I do this, all the items move to the left of the screen and some of them disappear completely.
Below is an image of the screen I need more space for:
Not enough space
Below is my python file for what I attempted:
import sqlite3
from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivy.lang import Builder
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen, SwapTransition
from kivy.uix.scrollview import ScrollView
Builder.load_file('ALevelNEA.kv')
##Below are the classes for my different screens
class SignupScreen(Screen):
pass
class MenuScreen(Screen):
pass
class SigninScreen(Screen, ScrollView):
pass
## Below are the classes for my custom buttons, widgets and text fields
class NameField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class ConfirmPasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class NameField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class PasswordField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
pass
class EmailField(MDRelativeLayout):
text = StringProperty()
hint_text = StringProperty()
#email_field = ObjectProperty(None)
##Below is the code for my main app
class MainApp(MDApp):
def build(self):
sm = ScreenManager(transition= SwapTransition())
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SigninScreen(name = 'signin'))
sm.add_widget(SignupScreen(name='signup'))
return sm
def RecordCheck(self):
print("clicked")
def AddToRecord(self, email, passw):
NewEmail = email
NewPassword = passw
# Connect to or create a new database
conn = sqlite3.connect('example.db')
# Create a cursor object to execute SQL commands
cursor = conn.cursor()
# Create a table to store the records
cursor.execute('''CREATE TABLE IF NOT EXISTS users (email TEXT, password TEXT)''')
# Insert the user's information into the table
cursor.execute("INSERT INTO users (email, password) VALUES (?, ?)", (NewEmail, NewPassword))
# Committing the changes and closing the connection to the database file
conn.commit()
conn.close()
if __name__ == '__main__':
MainApp().run()
Below is the section of my KV file which is relevant for what I attempted:
<SignupScreen>:
ScrollView:
GridLayout:
cols: 1
size_hint_y: None
height: self.minimum_height
padding: dp(10)
spacing: dp(10)
Image:
source: "Images/RegisterImage.png"
size_hint_x: 0.4
size_hint_y: 0.6
allow_stretch: True
pos_hint: {"center_x": 0.5, "center_y": 0.8 }
MDIconButton:
icon: "keyboard-backspace"
pos_hint: {"center_x": 0.35, "center_y": 0.95}
on_release:
root.manager.current = "menu"
EmailField:
id: email_widget
hint_text: "Email"
pos_hint: {"center_x": 0.5, "center_y": 0.55}
size_hint_x: None
width: "250dp"
NameField:
id: name_widget
hint_text: "Name"
pos_hint: {"center_x": 0.5, "center_y": 0.45}
size_hint_x: None
width: "250dp"
PasswordField:
id: passw_widget
size_hint_x: None
width: "250dp"
hint_text: "Password"
pos_hint: {"center_x": 0.5, "center_y": 0.35}
ConfirmPasswordField:
id: Cpass_widget
size_hint_x: None
width: "250dp"
hint_text: "Confirm Password"
pos_hint: {"center_x": 0.5, "center_y": 0.25}
MDRoundFlatButton:
text: "Sign up"
pos_hint: {"center_x": 0.5, "center_y": 0.15}
text_color: 0.3607, 0.3882, 1
line_color: 0, 0, 0
#on_release: app.AddToRecord()
on_release:
app.AddToRecord(root.ids.email_widget.ids.email_field.text, root.ids.passw_widget.ids.text_field.text)
MDLabel:
text: "by continuing you agree to the"
font_size: 15
halign: 'center'
pos_hint: {"center_y": 0.1}
MDTextButton:
text: "Terms and Conditions"
font_size: 15
pos_hint: {"center_x": 0.5, "center_y": 0.0825}
theme_text_color: "Custom"
text_color: 0.3607, 0.3882, 1
#Custom buttons and text fields are located below
<PasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<ConfirmPasswordField>:
size_hint_y: None
height: text_field.height
MDTextField:
id: text_field
hint_text: root.hint_text
text: root.text
password: True
icon_left: "lock"
MDIconButton:
icon: "eye-off"
pos_hint: {"center_y": .5}
pos: text_field.width - self.width + dp(8), 0
theme_text_color: "Hint"
on_release:
self.icon = "eye" if self.icon == "eye-off" else "eye-off"
text_field.password = False if text_field.password is True else True
<EmailField>:
size_hint_y: None
height: email_field.height
MDTextField:
id: email_field
hint_text: root.hint_text
text: root.text
icon_left: "email"
<NameField>:
size_hint_y: None
height: name_field.height
MDTextField:
id: name_field
hint_text: root.hint_text
text: root.text
icon_left: "account"
Below is the result:
Failed attempt (it does scroll but the layout is wrong)
Any help would be greatly appreciated, thanks!
A GridLayout is not required. Try using a BoxLayout, like this:
<SignupScreen>:
ScrollView:
BoxLayout:
orientation: 'vertical'
# cols: 1
from kivy.app import App
from kivy.graphics import Line
from kivy.metrics import dp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivymd.app import MDApp
class ScrollViewExample(ScrollView):
pass
class FirstWindow(Screen):
def set_text(self):
my_title_input = self.ids.note_title
my_details = self.ids.note_details
fo = open("notes.txt", "a")
fo.write('\n'+'\n'+my_title_input.text)
fo.write('\n'+my_details.text)
fo.close()
class SecondWindow(Screen):
pass
class ThirdWindow(Screen):
def on_toggle_button_state(self):
dark_mode = self.ids.dark_mode
dark_mode.text = 'Feature not available'
pass
class FourthWindow(Screen):
#This class displays notes from a file in buttons
#works but only the notes showup
def build(self):
root = FourthWindow()
root.add_widget(FourthWindow(name='StackLayout'))
class StackLayoutExample(StackLayout):
class ScrollView(ScrollView):
pass
def __init__(self, **kwargs):
super().__init__(**kwargs)
layout = StackLayout(orientation='lr-tb')
with open('notes.txt', 'r') as fp:
data = fp.read()
splat = data.split("\n\n")
notes = []
for i, note in enumerate(splat, 0):
notes.append(note)
for i in range(0, len(notes)):
b = Button(text=notes[i], size_hint=(.25, .4))
self.add_widget(b)
class WindowManager(ScreenManager):
pass
class RelativeLayoutExample(RelativeLayout):
pass
class ScreeManager(ScreenManager):
pass
class LineMaker(Widget):
pass
class Noteit(App):
pass
Noteit().run()
Noteit.kv <---The kv file begins here
WindowManager:
FirstWindow:
SecondWindow:
ThirdWindow:
FourthWindow:
<FirstWindow>:
id: first_window
name: "Notes"
RelativeLayout:
Label:
text: "Notes"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "left"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "right"
Label:
text: "Title:"
size_hint: None,None
pos_hint: {'top':.85,'center_x':.5}
font_size: 20
TextInput:
id: note_title
size_hint: .45,.08
pos_hint: {'top':.75,'center_x':.5}
multiline: False
Label:
text: "Details:"
size_hint: None,None
pos_hint: {'top':.65,'center_x':.5}
font_size: 20
TextInput:
id: note_details
size_hint: .45,.3
pos_hint: {'top':.55,'center_x':.5}
multiline: True
Button:
text: "Submit"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.25,'center_x':.5}
on_release:
root.set_text()
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
Button:
text: 'View All Notes'
size_hint:.25,.15
pos_hint: {'bottom':1,'center_x':.5}
on_release:
app.root.current = "View"
root.manager.transition.direction= "up"
<SecondWindow>:
name: "Account"
RelativeLayout:
Label:
text: "Account"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "right"
Button:
text: 'Preferences'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Preferences"
root.manager.transition.direction= "left"
Label:
text: "Username:"
size_hint: None,None
pos_hint: {'top':.85}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.55,'left':.3}
multiline: False
Label:
text: "Password:"
size_hint: None,None
pos_hint: {'top':.65}
font_size: 20
TextInput:
size_hint: .5,.1
pos_hint: {'top':.75,'left':.3}
multiline: False
Button:
text: "Log In"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45}
Button:
text: "Sign Up"
size_hint: .25,.1
length: "100dp"
pos_hint: {'top':.45,'center_x':.375}
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<ThirdWindow>:
name: "Preferences"
RelativeLayout:
Label:
text: "Preferences"
size_hint: None,None
pos_hint: {'top':1,'center_x':.5}
font_size: 35
Button:
text: 'Notes'
size_hint: None,None
pos_hint: {'top':1,'right':1}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "left"
Button:
text: 'Account'
size_hint: None,None
pos_hint: {'top':1,'left':1}
on_release:
app.root.current = "Account"
root.manager.transition.direction= "right"
ToggleButton:
text: 'Dark Mode'
size_hint: .25,.1
pos_hint: {'top':.75,'center_x':.25}
on_state: root.on_toggle_button_state()
Label:
id: dark_mode
text: ''
LineMaker:
canvas:
Color:
rgba: 1, 1, 1, 1
Line:
width: 2.
points: (self.width,self.height*.83,0,self.height*.83)
<FourthWindow>:
name: "View"
RelativeLayout:
Button:
text: 'Note Submission'
size_hint:.25,.15
pos_hint: {'top':1,'center_x':.5}
on_release:
app.root.current = "Notes"
root.manager.transition.direction= "down"
Label:
text: 'All Notes'
size_hint: None,None
pos_hint: {'top':1,'right':.9}
font_size: 35
How do I make the stacklayout code showup with the kv file code? Or at least make the stacklayout part of the screen.
Right now the only option I have is either take the screen as output or the stack layout as output.
Replacing the def build(self) inside the class FourthWindow(Screen) will show the whole application. The code inside the def build(self) also works but they do not work together.
I am new to kivy and object oriented programming so I do not know much about this topic so I could be missing something really basic.
I'm trying to put the username that I input from an MDTextField into a MDLabel text. In my case, the MDLabel is in a MDNavigationDrawer that comes after the user presses the submit button and goes to the next screen.
All I could think of so far is declaring usn as a string property in the submit screen:
class SubmitScreen(Screen):
usn = StringProperty()
then created a method to set usn to the input of the MDTextfield in my app:
def getname(self):
usn = (self.root.get_screen("menu").ids.userdata.text)
then I set the text in my MDLabel to root.usn
MDLabel:
text: root.usn
font_style: 'Subtitle1'
size_hint_y:None
height: self.texture_size[1]
When I go to the next screen, MDLabel is blank. It doesn't give me an error but it doesn't show what I typed in the MDTextField, it's simply blank.
This is my code in full:
screen_helper = """
ScreenManager:
MenuScreen:
SubmitScreen:
<MenuScreen>:
name: 'menu'
MDTextField:
id : userdata
hint_text: "Enter Username"
helper_text: "or click on forgot username"
#helper_text_mode: "persistent"
helper_text_mode: "on_focus"
icon_right: "account"
icon_right_color: app.theme_cls.primary_color
pos_hint : {'center_x': 0.5, 'center_y': 0.4}
size_hint_x:None
width:250
mode : "rectangle"
MDTextField:
id: userpass
hint_text: "Enter Password"
helper_text: "or click on forgot Password"
#helper_text_mode: "persistent"
password : True
helper_text_mode: "on_focus"
icon_right: "eye-off"
icon_right_color: app.theme_cls.primary_color
pos_hint : {'center_x': 0.5, 'center_y': 0.3}
size_hint_x:None
width:250
mode : "rectangle"
MDLabel:
text: "Company X"
pos_hint: {'center_x':0.5, 'center_y':0.7}
font_style: 'H3'
halign: 'center'
MDRectangleFlatButton:
text: 'Submit'
pos_hint: {'center_x':0.5, 'center_y':0.2}
font_size : 20
on_press:
app.getname()
app.root.current = 'submit'
<SubmitScreen>:
name: 'submit'
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "Company X"
left_action_items: [["menu", lambda x : nav_drawer.toggle_nav_drawer()]]
elevation: 11
Widget:
MDFillRoundFlatIconButton:
spacing: '8dp'
padding: '20dp'
text: 'Menu'
pos_hint: {'center_x':0.5, 'center_y':0.9}
icon: 'account-child'
on_press: root.manager.current = 'menu'
MDFillRoundFlatIconButton:
text: 'View Account'
pos_hint: {'center_x':0.5, 'center_y':1}
font_size : 20
icon: 'account-cash'
on_press:
MDBottomAppBar:
md_bg_color: 0, 1, 0, 1
MDToolbar:
title: "by Tech Company"
left_action_items: [["coffee", lambda x : app.navigation_draw0()]]
right_action_items: [["clock", lambda x : app.navigation_draw1()]]
mode: 'free-end'
elevation: 13
type: 'bottom'
icon: 'account-check'
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation: 'vertical'
spacing: '8dp'
padding: '12dp'
Image:
source: 'img.jpg'
MDLabel:
text: root.usn
font_style: 'Subtitle1'
size_hint_y:None
height: self.texture_size[1]
MDLabel:
text: 'email#gmail.com'
font_style: 'Caption'
size_hint_y:None
height: self.texture_size[1]
ScrollView:
MDList:
#OneLineListItem:
OneLineIconListItem:
text: 'Profile'
IconLeftWidget:
icon: 'face-profile'
OneLineIconListItem:
text: 'Upload'
IconLeftWidget:
icon: 'upload'
OneLineIconListItem:
text: 'Logout'
conLeftWidget:
icon: 'logout'
MDRectangleFlatButton:
text: 'Menu'
pos_hint: {'center_x':0.5, 'center_y':0.4}
on_press: root.manager.current = 'menu'
MDRectangleFlatButton:
text: 'View Account'
pos_hint: {'center_x':0.5, 'center_y':0.3}
on_press:
"""
class MenuScreen(Screen):
pass
class SubmitScreen(Screen):
usn = StringProperty()
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SubmitScreen(name='submit'))
sm.add_widget(UploadScreen(name='upload'))
sm.add_widget(AccountScreen(name='account'))
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
self.theme_cls.primary_palette = "Purple"
self.theme_cls.accent_palette = 'Blue'
self.theme_cls.primary_hue = "200"
self.theme_cls.theme_style = "Dark"
return screen
def getname(self):
usn = (self.root.get_screen("menu").ids.userdata.text)
DemoApp().run()
Set an ID to the MDLabel and then in the getname function change the MDLabel text to the input of the MDTextField.
In kv:
MDLabel:
text: "Text before"
id: label
In python:
def getname(self):
usn = (self.root.get_screen("menu").ids.userdata.text)
self.root.ids.label.text = usn
I have a kivy app I built, that receives a message from a server, saves it into a text file, and displays the text file onto the screen. However, the text always exceeds the ScrollView widget and goes onto some other widgets like the picture below.
Is there any ways to solve this? Any help will be appreciated. Thank You.
This is my code:
#Todo: fix line 334 AttributeError
#Remove the upload button also
#Error Fixed
#Todo: fix message received exceeds border error
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivymd.dialog import MDDialog
from kivymd.theming import ThemeManager
from kivymd.navigationdrawer import NavigationLayout
from kivymd.list import OneLineAvatarListItem, ILeftBody
from kivymd.toast import toast
from kivymd.dialog import MDDialog
from kivy.uix.popup import Popup
from threading import Thread
import socket
sock = socket.socket()
sock.connect(('127.0.0.1', 6818))
sock.sendall(b"add_contact hello llo")
sock = socket.socket()
sock.connect(('127.0.0.1', 6818))
sock.sendall(b'new llo')
class MyLayout(BoxLayout):
scr_mngr = ObjectProperty(None)
def check_data_login(self):
username = self.scr_mngr.screen1.username.text
password = self.scr_mngr.screen1.password.text
print(username)
print(password)
if username == "KivyMD" and password == "kivy":
self.ids["wrongpass"].text = ""
self.change_screen("screen2")
else:
self.ids["wrongpass"].text = "Wrong username or password, please try again"
def change_screen(self, screen, *args):
self.scr_mngr.transition.direction = 'left'
self.scr_mngr.current = screen
def back_to_chat(self):
self.scr_mngr.transition.direction = 'right'
self.scr_mngr.current = 'screen2'
class nav_layout(NavigationLayout):
def print_text(self):
print('hello')
def check_data_login(self):
username = self.ids.screen1.username.text
password = self.ids.screen1.password.text
print(username)
print(password)
if username == "KivyMD" and password == "kivy":
Thread(target=self.recover_data).start()
self.change_screen("screen2")
self.ids.wrongpass.text = ""
else:
self.ids.wrongpass.text = \
"Wrong username or password, please try again"
def recover_data(self):
print('started')
while True:
data = sock.recv(1024)
data = data.decode()
if data:
print(data)
data = data.split()
data = data[-1] + ": " + ' '.join(data[:-1])
r = data + '\n'
open('chat1.txt', 'a+').write(r)#Fix The the Attribute Error that occurs when a message is sent!!!!!
e = open('chat1.txt', 'r').readlines()
self.ids.Chat_String.text = '\n\r'.join(e)
print(data)
def change_screen(self, screen, *args):
self.ids.scr_mngr.transition.direction = 'left'
self.ids.scr_mngr.current = screen
def back_to_chat(self):
self.ids.scr_mngr.transition.direction = 'right'
self.ids.scr_mngr.current = 'screen2'
def logout(self):
# logout function, returns to screen 1
self.ids.scr_mngr.current = 'screen1'
class UploadPopup(Popup):
def load(self, path, selection):
print(path, selection)
KV = """
#: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 MDTextField kivymd.textfields.MDTextField
#:import MDSeparator kivymd.card.MDSeparator
#:import MDThemePicker kivymd.theme_picker.MDThemePicker
#:import CardTransition kivy.uix.screenmanager.CardTransition
#:import Factory kivy.factory.Factory
<MDCustomIconItem>:
text: root.text
AvatarSampleWidget:
source: root.icon
<UploadPopup>:
id: popup
title: "Upload"
BoxLayout:
FileChooserIconView:
id: FileChoose
pos_hint_x: 0.5
pos_hint_y: 0.5
on_selection: root.load(FileChoose.path, FileChoose.selection)
MDRaisedButton:
text: "Upload"
text_color: (0,0,0,1)
on_release: root.load(FileChoose.path, FileChoose.selection)
on_release: popup.dismiss()
MDRaisedButton:
text: "Close"
text_color: (0,0,0,1)
on_release: popup.dismiss()
nav_layout:
id: nav_layout
MDNavigationDrawer:
id: nav_drawer
drawer_logo: 'logo.png'
NavigationDrawerToolbar:
title: 'hello'
NavigationDrawerIconButton:
icon: 'settings'
text: 'Account Settings'
on_release: root.change_screen('screen3')
NavigationDrawerIconButton:
icon: 'face'
text: 'Friends'
on_release: root.print_text()
NavigationDrawerIconButton:
icon: 'logout'
text: 'Logout'
on_release: root.logout()
NavigationDrawerDivider:
height: dp(1)
MyLayout:
scr_mngr: scr_mngr
orientation: 'vertical'
ScreenManager:
transition: CardTransition()
id: scr_mngr
screen1: screen1
Screen:
id: screen1
name: 'screen1'
username: username
password: password
BoxLayout:
size_hint: None, None
size: dp(520), dp(340)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
BoxLayout:
orientation:'vertical'
padding: dp(20)
spacing:20
MDLabel:
text: 'Chat App'
theme_text_color: 'Secondary'
font_style:"Title"
size_hint_y: None
height: dp(36)
MDSeparator:
height: dp(1)
MDTextField:
id: username
hint_text: "Username "
size_hint_y: 0.9
helper_text_mode: "on_focus"
MDTextField:
id: password
hint_text: "Password "
helper_text_mode: "on_focus"
size_hint_y: 0.9
password: True
MDFlatButton:
text: "Login"
pos_hint: {'center_x': 0.5}
on_release: root.check_data_login()
MDLabel:
id: wrongpass
color: 1,0,1,1
text: ""
Screen:
name: 'screen2'
id: screen2
Toolbar:
id: toolbar
title: "Welcome ! "
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
MDLabel:
id: data
font_style: 'Title'
theme_text_color: 'Primary'
text: "Data :"
height: self.texture_size[1] + dp(3)
halign: 'center'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
Screen:
name: 'screen3'
id: screen3
Toolbar:
id: tools
title: "Your Profile"
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['arrow-left', lambda x: root.back_to_chat()]]
MDLabel:
id: Profile_String
font_size: 90
text: "XXX"
halign: 'center'
pos_hint: {'center_x': 0.5, 'center_y': 0.85}
Screen:
name: 'screen4'
id: screen4
Toolbar:
id: tools
title: "XXX"
pos_hint: {'center_x': 0.5, 'center_y': 0.96}
md_bg_color: app.theme_cls.primary_color
background_palette: 'DeepPurple'
background_hue: 'A400'
left_action_items: [['menu', lambda x: app.root.toggle_nav_drawer() ]]
right_action_items: [['animation', lambda x: MDThemePicker().open()], ['camera', lambda x: print('hello')]]
ScrollView:
pos_hint: {'center_x': .55, 'y': .35}
MDLabel:
size_hint: 1, None
id: Chat_String
font_size: 40
text: "XXX"
MDTextField:
id: Input_String
hint_text: 'Enter Your Message...'
helper_text_mode: 'on_focus'
pos_hint: {'center_x': 0.35, 'center_y': 0.2}
size_hint_x: 0.6
multiline: True
MDRaisedButton:
id: Send_Button
text: 'Send'
pos_hint: {'center_x': 0.75, 'center_y': 0.2}
MDRaisedButton:
id: Choose_Image
text: 'Attach File'
pos_hint: {'center_x': 0.9, 'center_y': 0.2}
on_release: Factory.UploadPopup().open()
"""
class MDCustomIconItem(OneLineAvatarListItem):
icon = StringProperty('')
text = StringProperty()
def _set_active(self, active, list):
pass
class AvatarSampleWidget(ILeftBody, Image):
pass
class MyApp(App):
theme_cls = ThemeManager()
theme_cls.primary_palette = 'Blue'
title = "Navigation Drawer"
main_widget = None
def __getattr__(self, attr):
return super().__getattr__(attr)
def build(self):
self.main_widget = Builder.load_string(KV)
return self.main_widget
def callback(self, instance, value):
self.main_widget.ids.scr_mngr.current = 'screen4'
def on_start(self):
for i in range(15):
self.main_widget.ids.nav_drawer.add_widget(
MDCustomIconItem(
text="Item menu %d" % i,
icon='logo.png',
on_release=lambda x, y=i: self.callback(x, y)))
MyApp().run()
You need to set the size of the ScrollView. Add size_hint: (0.85, 0.55)
Snippets
ScrollView:
size_hint: (0.85, 0.55)
pos_hint: {'center_x': .55, 'y': .35}
MDLabel:
id: Chat_String
font_size: 40
Output