Reputation: 27
'''I am relatively new to kivy so I would really appreciate any help given. I have been stuck with this problem: if self.name.text != "" and self.username.text != "" and self.password.text != "": AttributeError: 'str' object has no attribute 'text . This problem is faced in the python code's SignupScreen. I have tried placing a "text" argument into: def submit(self, text) However, it returns me with another error: TypeError: submit() missing 1 required positional argument: 'text'. Would appreciate any advice/ help given. '''
class SignupScreen(Screen):
name = ObjectProperty(None)
username = ObjectProperty(None)
password = ObjectProperty(None)
def submit(self):
if self.name.text != "" and self.username.text != "" and self.password.text != "":
added = db.add_user(self.username.text, self.password.text, self.name.text)
if added == 1:
self.reset()
wm.current = "login"
elif added == 2:
PassTooShort()
else:
AccAlreadyExists()
else:
invalidForm()
def login(self):
self.reset()
wm.current = "login"
def reset(self):
self.username.text = ""
self.password.text = ""
self.name.text = ""
# Invalid input handling functions
def invalidLogin():
pop = Popup(title='Invalid Login',
content=Label(text='Invalid username\nor password.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def invalidForm():
pop = Popup(title='Invalid Form',
content=Label(text='Invalid fields. Try again.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def AccAlreadyExists():
pop = Popup(title='Invalid Form (User Exists)',
content=Label(text='Enter a unique\nUsername.'),
size_hint=(None, None), size=(400, 400))
pop.open()
def PassTooShort():
pop = Popup(title='Invalid Form (Password Too Short)', content=Label(text='Password is too short. Try again.'), size_hint=(None, None), size=(400, 400))
pop.open()
wm = WindowManager()
db = DataBase("users.db")
wm.current = "welcome"
class MyMainApp(MDApp):
def build(self):
self.kv = Builder.load_file("main.kv")
return self.kv
if __name__ == "__main__":
MyMainApp().run()
'''The below is my Kivy code:'''
<SignupScreen>:
name: "signup"
n: name
username: username
password: passw
MDFloatLayout:
md_bg_color: 1,1,1,1
MDIconButton:
icon: "arrow-left"
pos_hint: {"center_y": .95}
user_font_size: "30sp"
theme_text_color: "Custom"
text_color: rgba(26, 24, 58, 255)
on_release:
app.root.transition.direction = "right"
app.root.current = "welcome"
MDLabel:
text: "H i !"
font_name: "BPoppins"
font_size: "30sp"
pos_hint: {"center_x": .5, "center_y": .85}
halign: "center"
color: rgba(0, 0, 59, 255)
MDLabel:
text: "Create a new account"
font_name: "MPoppins"
font_size: "18sp"
pos_hint: {"center_x": .5, "center_y": .79}
halign: "center"
color: rgba(135, 135, 193, 255)
MDFloatLayout: #Creating name
size_hint: .45, .07
pos_hint: {"center_x": .5, "center_y": .68}
TextInput:
id: name
hint_text: "Name"
font_name: "MPoppins"
pos_hint: {"center_x": .445, "center_y": .5}
background_color: 1,1,1,0
foreground_color: rgba(0,0,59,255)
cursor_color: rgba(0,0,59,255)
font_size: "14sp"
cursor_width: "2sp"
multiline: False
MDFloatLayout:
pos_hint: {"center_x": .45, "center_y": 0}
size_hint_y: .03
md_bg_color: rgba(178, 178, 178, 255)
MDFloatLayout: #Creating username
size_hint: .45, .07
pos_hint: {"center_x": .5, "center_y": .56}
TextInput:
id: username
hint_text: "Username"
font_name: "MPoppins"
pos_hint: {"center_x": .445, "center_y": .5}
background_color: 1,1,1,0
foreground_color: rgba(0,0,59,255)
cursor_color: rgba(0,0,59,255)
font_size: "14sp"
cursor_width: "2sp"
multiline: False
MDFloatLayout:
pos_hint: {"center_x": .45, "center_y": 0}
size_hint_y: .03
md_bg_color: rgba(178, 178, 178, 255)
MDFloatLayout: #Creating password
size_hint: .45, .07
pos_hint: {"center_x": .5, "center_y": .44}
TextInput:
id: passw
hint_text: "Password"
font_name: "MPoppins"
pos_hint: {"center_x": .445, "center_y": .5}
background_color: 1,1,1,0
foreground_color: rgba(0,0,59,255)
cursor_color: rgba(0,0,59,255)
font_size: "14sp"
cursor_width: "2sp"
multiline: False
password: True
MDFloatLayout:
pos_hint: {"center_x": .45, "center_y": 0}
size_hint_y: .03
md_bg_color: rgba(178, 178, 178, 255)
Button: #Creating log in button
text: "SIGN UP"
size_hint: .35, .065
pos_hint: {"center_x": .5, "center_y": .3}
background_color: 0,0,0,0
font_name: "BPoppins"
canvas.before:
Color:
rgb: rgba(52, 0, 231, 255)
RoundedRectangle:
size: self.size
pos: self.pos
radius: [5]
on_release:
app.root.transition.direction = "right"
root.submit()
MDLabel:
text: "or"
color: rgba(52, 0, 231, 255)
pos_hint: {"center_y": 0.2}
font_size: "13sp"
font_name: "BPoppins"
halign: "center"
MDFloatLayout:
md_bg_color: rgba(178, 178, 178, 255)
size_hint: .162, .002
pos_hint: {"center_x": .405, "center_y": .196}
MDFloatLayout:
md_bg_color: rgba(178, 178, 178, 255)
size_hint: .162, .002
pos_hint: {"center_x": .595, "center_y": .196}
MDTextButton:
text: "Already have an account?"
pos_hint: {"center_x": 0.47, "center_y": 0.15}
color: rgba(68, 78, 132, 255)
font_size: "12sp"
font_name: "BPoppins"
MDTextButton:
text: "Sign in"
font_name: "BPoppins"
font_size: "12sp"
pos_hint: {"center_x": 0.58, "center_y": 0.15}
color: rgba(52, 0, 213, 255)
on_release:
app.root.transition.direction = "left"
app.root.current = "login"
Upvotes: 1
Views: 755
Reputation: 27
'''
database.py (The database code that I use for the above)
'''
import datetime
import sqlite3
import hashlib
import os
class DataBase:
def __init__(self, conn):
self.conn = sqlite3.connect(conn)
self.users = None
self.load()
def load(self):
self.conn.execute("CREATE TABLE IF NOT EXISTS users (username VARCHAR(20) UNIQUE, name VARCHAR(50), passw BLOB, salt BLOB, createdOn DATE); ")
self.conn.commit()
def get_user(self, username):
try:
self.conn.execute("SELECT username FROM users WHERE (username = ?);", (username,))
self.conn.commit()
return 1
except sqlite3.Error:
return -1
def add_user(self, username, password, name):
if len(list(password)) <= 3:
return 2
else:
salt = os.urandom(32)
hash = hashlib.sha512()
hash.update(('%s%s' % (salt, password)).encode('utf-8'))
hashPass = hash.hexdigest()
try:
self.conn.execute("INSERT INTO users (username, name, passw, salt, createdOn) VALUES (?, ?, ?, ?, ?)",
(username, name, hashPass, salt, self.get_date()))
self.conn.commit()
return 1
except sqlite3.Error:
print("error")
return -1
def validate(self, username, password):
user = self.conn.execute("SELECT * FROM users WHERE (username = ?);", (username,)).fetchall()
if user:
salt = user[0][3]
hash = hashlib.sha512()
hash.update(('%s%s' % (salt, password)).encode('utf-8'))
hashPass = hash.hexdigest()
if hashPass == str(user[0][2]):
return True
else:
return False
else:
return False
@staticmethod
def get_date():
return str(datetime.datetime.now()).split(" ")[0]
Upvotes: 0
Reputation: 38937
The root of your problem is a confusion of the name
property of SignupScreen
. After examining your code more closely, I see:
MDFloatLayout: #Creating name
size_hint: .45, .07
pos_hint: {"center_x": .5, "center_y": .68}
TextInput:
id: name
and:
<SignupScreen>:
name: "signup"
n: name
username: username
password: passw
Any Screen
has a name
property that identifies the Screen
to its ScreenManager
. I believe your code is confusing this name
property with the name of that the user is expected to enter in the TextInput
with the id
of name
. I suggest you use a different id
and ObjectProperty
to keep these properties clear. For example, you cold change the first bit of code to:
MDFloatLayout: #Creating name
size_hint: .45, .07
pos_hint: {"center_x": .5, "center_y": .68}
TextInput:
id: personname # different id to clear up confusion
and in the SignupScreen
rule:
<SignupScreen>:
name: "signup"
personname: personname
username: username
password: passw
and, of course, this requires corresponding changes in the SignupScreen
code:
class SignupScreen(Screen):
personname = ObjectProperty(None)
username = ObjectProperty(None)
password = ObjectProperty(None)
def submit(self):
if self.personname.text != "" and self.username.text != "" and self.password.text != "":
added = db.add_user(self.username.text, self.password.text, self.personname.text)
if added == 1:
self.reset()
wm.current = "login"
elif added == 2:
PassTooShort()
else:
AccAlreadyExists()
else:
invalidForm()
def login(self):
self.reset()
wm.current = "login"
def reset(self):
self.username.text = ""
self.password.text = ""
self.personname.text = ""
Upvotes: 1
Reputation: 38937
self.name
is a string:
<SignupScreen>:
name: "signup"
to trying to access self.name.text
will throw that exception. Just use self.name
without the .text
.
Upvotes: 0