KivyMD - ScreenManager 和 ids

Posted

技术标签:

【中文标题】KivyMD - ScreenManager 和 ids【英文标题】:KivyMD - ScreenManager and ids 【发布时间】:2021-10-14 11:47:31 【问题描述】:

大家还好吗?我正在学习 KivyMD 和 ScreenManager,但我遇到了一个小问题(也是一个大问题)。我正在编写一个程序(就像大多数初学者一样),它允许用户登录或注册(我也在练习 sqlite3,但我对此没有问题)。 首先,我尝试只在一个屏幕上完成所有操作,而且效果很好!

但是现在,当我尝试使用任何功能时,我得到:

_username = self.root.ids.my_username.text

AttributeError: 'super' object has no attribute '__getattr__'

py 文件是:

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import sqlite3

class MainMenu(Screen):
    pass

class LogIn(Screen):
    pass

class SignUp(Screen):
    pass

class MainLogSignApp(MDApp):

    def build(self):

        # Connect to databse an create a cursor
        conn = sqlite3.connect('user_pass.db')
        c = conn.cursor()

        c.execute("""CREATE TABLE if not exists user_name(
                username text,
                password text
            )""")

        conn.commit()
        conn.close()

        return Builder.load_file('mainlogsign.kv')


        return sm

    def submit_info(self):
        '''If the info does not exist, it adds it to the table;
        If it does, the function check if it is correct'''

        _username = self.root.ids.my_username.text
        _password = self.root.ids.my_password.text

        # Connect and create cursor
        conn = sqlite3.connect('user_pass.db')
        c = conn.cursor()

        # This should not be necesary, but it is here just in case I delete the table using     the DELETE button.
        c.execute("""CREATE TABLE if not exists user_name(
                username text,
                password text
            )""")

        c.execute("SELECT * FROM user_name WHERE username = (?)", (_username,))
        already_in = c.fetchone()

        if already_in and already_in[0]:
            self.root.ids.my_message.text = already_in[0] + '\nUser already exists'
        else:
            c.execute("INSERT INTO user_name VALUES (?,?)", (_username, _password))
            self.root.ids.my_message.text = 'User added successfully'

        conn.commit()
        conn.close()

        self.root.ids.my_username.text = ''
        self.root.ids.my_password.text = ''


# THERE ARE MORE FUNCTIONS, BUT THEY ALL HAVE THE SAME PROBLEM.

if __name__ == '__main__':
    MainLogSignApp().run()

kivy 文件是:

ScreenManager:
    MainMenu:
    LogIn:
    SignUp:

<MyTextField@MDTextFieldRound>:
    font_size: 12
    size_hint_x: 0.6
    pos_hint: 'center_x': 0.5
    halign: 'center'


<MainMenu>:
    name: 'main_menu'

    BoxLayout:
        orientation: 'vertical'

        Label:
            size_hint: .1, .3

        MDRoundFlatButton:
            text: 'LOG IN'
            pos_hint: 'center_x': .5
            on_press: 
                root.manager.current = 'login'
                root.manager.transition.direction = 'left'

        Label:
            size_hint: .1, .1

        MDRoundFlatButton:
            text: 'SIGN UP'
            pos_hint: 'center_x': .5
            on_press: 
                root.manager.current = 'signup'
                root.manager.transition.direction = 'left'

        Label:
            size_hint: .1, .3


<LogIn>:
    name: 'login'

    BoxLayout:
        orientation: 'vertical'
    
        MDLabel:
            text: 'LOGIN'
            halign: 'center'
        
        Button:
            id: my_label_l
            text: 'DELETE'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5
            halign: 'center'
            on_press: app.delete_record()

        MyTextField:
            id: my_username_l
            hint_text: 'Enter your username'
            icon_right: 'account'

        MyTextField:
            id: my_password_l
            hint_text: 'Enter your password'
            icon_right: 'eye-outline'

        Button:
            id: log_in
            text: 'LOG IN'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5
            on_press: app.log_in()

        Button:
            id: show_button_l
            text: 'Nothing'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5

        MDLabel:
            id: my_message_l
            text: ''
            halign: 'center'

        MDRectangleFlatIconButton:
            icon: 'backspace-outline'
            on_press: 
                root.manager.current = 'main_menu'
                root.manager.transition.direction = 'right'



<SignUp>:
    name: 'signup'

    BoxLayout:
        orientation: 'vertical'
        MDLabel:
            text: 'SIGNUP'
            halign: 'center'

        Button:
            id: my_label
            text: 'DELETE'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5
            halign: 'center'
            on_press: app.delete_record()

        MyTextField:
            id: my_username
            hint_text: 'Enter your username'
            icon_right: 'account'

        MyTextField:
            id: my_password
            hint_text: 'Enter your password'
            icon_right: 'eye-outline'

        Button:
            id: submit_button
            text: 'Submit info'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5
            on_press: app.submit_info()

        Button:
            id: show_button
            text: 'Show records'
            size_hint: 0.6, 0.2
            pos_hint: 'center_x': .5
            on_press: app.show_info()

        MDLabel:
            id: my_message
            text: ''
            halign: 'center'

        MDRectangleFlatIconButton:
            icon: 'backspace-outline'
            on_press: 
                root.manager.current = 'main_menu'
                root.manager.transition.direction = 'right'

这些函数都不起作用,所以我猜它与 'app.function()' 或 ID 有关,但它第一次确实起作用。也许我必须使用不同的路径,但我不知道。

作为一个小问题,当我在 TextInput 上书写时,提示文本不会消失。知道为什么吗?

谢谢!

顺便说一句,您可能会注意到“删除”和“显示记录”按钮,并认为它们与登录或注册程序无关。你再正确不过了!!所以不要关注他们。我只添加了这些按钮来使用 sqlite3,但在真正的应用程序或网站上它们不会存在。不过,任何按钮的问题都是一样的。

【问题讨论】:

嗨@Jorge Nuñez,你的kivymd 版本是什么? @Yous-s-riAboElseod 抱歉耽搁了,我整个周末都在工作。我的kivy版本是2.0.0 我解决了这个问题。只是一些修改。 【参考方案1】:

好的,我已经解决了这个问题。我将函数 submit_info 写入 SignUp 类并将 app.submit_info() 更改为 root.submit_info() (在 kv 文件中)。此外,我必须删除每个“根”。在函数中。

如果有人遇到同样的问题,我希望这能奏效。

【讨论】:

以上是关于KivyMD - ScreenManager 和 ids的主要内容,如果未能解决你的问题,请参考以下文章

使用按钮更改 kivy 或 kivymd 中的屏幕

在 KivyMD Python 中将数据存储在 JSON 文件中时出错

使用 My TOOLBAR 和 SCREEN MANAGER 最小化我的代码

kivy:全局变量和 ScreenManager

Kivy 无法使用 ScreenManager 获取文本输入

在 Kivy 1.10 和 Python 2.7.9 中使用 ScreenManager 获取 TextInput 值