Jorge Nuñez
Jorge Nuñez

Reputation: 43

KivyMD - ScreenManager and ids

How's everyone doing? I am learning about KivyMD and ScreenManager and I have a little problem (and a big one). I was writing a program (like most beginners do) which would allow a user to log in or sign up (I was also practicing about sqlite3, but I don't have a problem with that). First, I've tried to do everything in only one screen and it worked perfectly!

But now, when I try to use any function, I get:

_username = self.root.ids.my_username.text

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

The py file is:

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

And the kivy file is:

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'

None of the functions work, so I'm guessing it has something to do with 'app.function()' or the ids, but it did work the first time. Maybe I have to use a different path, but I don't know.

As a small problem, when I write on the TextInput the hint text doesn't disappear. Any idea why?

Thanks!

BTW, you may notice the button 'DELETE' and 'SHOW RECORDS' and think they have nothing to do with a Login or SignUp program. You couldn't be more right!! So don't pay attention to them. I only added those button to work with sqlite3, but on a real app or site they wouldn't be there. Still, the problem is the same with any button.

Upvotes: 1

Views: 843

Answers (1)

Jorge Nu&#241;ez
Jorge Nu&#241;ez

Reputation: 43

Ok, I've solved the problem. I wrote the function submit_info into the SignUp class and change the app.submit_info() to root.submit_info() (in the kv file). Also, I had to remove every "root." in the function.

I hope this works if anybody gets the same problem.

Upvotes: 1

Related Questions