【问题标题】:Kivy: AttributeError: 'str' object has no attribute 'text'Kivy:AttributeError:'str'对象没有属性'text'
【发布时间】:2021-09-03 17:01:04
【问题描述】:

'''我对 kivy 比较陌生,所以我非常感谢您提供的任何帮助。我一直被这个问题困扰:如果 self.name.text != "" and self.username.text != "" and self.password.text != "": AttributeError: 'str' 对象没有属性 'text 。在 python 代码的 SignupScreen 中面临这个问题。我尝试将“文本”参数放入: def 提交(自我,文本) 但是,它返回给我另一个错误:TypeError: submit() missing 1 required positional argument: 'text'。将不胜感激任何建议/帮助。 '''

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()

'''下面是我的 Kivy 代码:'''

<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"   
        

【问题讨论】:

  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。

标签: python kivy


【解决方案1】:

self.name 是一个字符串:

<SignupScreen>:
    name: "signup"

尝试访问self.name.text 将引发该异常。只需使用self.name 而不使用.text

【讨论】:

  • 当我在 python 代码中删除名称、用户名和密码的 .text 时,遇到的错误是:文件“kivy\weakproxy.pyx”,第 293 行,在 kivy.weakproxy.WeakProxy 中。 __iter__ TypeError: 'TextInput' 对象不可迭代
【解决方案2】:

问题的根源在于混淆了SignupScreenname 属性。在仔细检查您的代码后,我看到:

    MDFloatLayout:   #Creating name
        size_hint: .45, .07
        pos_hint: {"center_x": .5, "center_y": .68}
        TextInput:
            id: name

和:

<SignupScreen>:
    name: "signup"
    n: name
    username: username
    password: passw

任何Screen 都有一个name 属性,该属性将Screen 标识为其ScreenManager。我相信您的代码将这个name 属性与用户在TextInput 中输入的名称与idname 混淆了。我建议您使用不同的idObjectProperty 来保持这些属性清晰。例如,您将代码的第一位冷更改为:

    MDFloatLayout:   #Creating name
        size_hint: .45, .07
        pos_hint: {"center_x": .5, "center_y": .68}
        TextInput:
            id: personname  # different id to clear up confusion

SignupScreen 规则中:

<SignupScreen>:
    name: "signup"
    personname: personname
    username: username
    password: passw

当然,这需要对SignupScreen代码进行相应的更改:

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 = ""

【讨论】:

  • 现在可以使用了!十分感谢你的帮助!我现在意识到注册屏幕不断从“AccAlreadyExists”函数返回弹出窗口。我的代码有问题吗?我创建了一个存储密码的数据库 python 代码和 sql
  • 这应该作为一个新问题发布。
【解决方案3】:

''' database.py(我在上面使用的数据库代码) '''
导入日期时间 导入 sqlite3 导入哈希库 导入操作系统

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]

【讨论】:

    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多