confusionm
confusionm

Reputation: 59

python - kivy: Call function from another class

I am currently developing a GUI with Python/ Kivy and have some issues when it comes to call a function from another class. I set up a screen, which includes a TextInput widget, that can be used to insert an E-Mail address. By clicking the Submit-Button, the function 'check_mail' is called, which checks the E-Mail using regular expressions and then either prints a text ('E-Mail not valid') or changes the screen (The E-Mail Address will later be transferred to a database, for now its fine to just change the screen after submitting). However, the function does print me the text, if the E-Mail format is not valid, but when it comes to call the change_screen function from the InsertData class, it is not working (AttributeError: 'NoneType' object has no attribute 'ids') If I call the change_screen function within the .kv file {on_release: app.change_screen('home_screen')}, it works fine. How can I access the change_screen function from my InsertData class?

main.py

class HomeScreen(Screen):
    pass

class InsertData(Screen):
    def check_mail(self):
        addressToVerify = self.ids.email_main.text
        match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', addressToVerify)
        if match == None:
            print('Email not valid!')
        else:
            MainApp().change_screen('home_screen')

GUI = Builder.load_file("main.kv")

class MainApp(App):

    def build(self):
        return GUI    
    def change_screen(self, screen_name):
        screen_manager = self.root.ids[
            'screen_manager']
        screen_manager.transition = CardTransition()
        screen_manager.transition.direction = 'up'
        screen_manager.transition.duration = .3
        screen_manager.current = screen_name    

MainApp().run()

insert_data.kv

<InsertData>:
    FloatLayout:
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
                source: "background/background_main.png"
   GridLayout:
       rows: 1
       pos_hint: {"top": 1, "right": 1}
       size_hint: 1, .8
       TextInput:
           id: email_main
           hint_text: "E-Mail Address"
       LabelButton:       
           text: "Submit"
           on_release:
               root.check_mail()

Upvotes: 0

Views: 2473

Answers (3)

filza
filza

Reputation: 1

I have some solution just to show how does it will work.

class A (self): def some_method(self): print("Print Here")

class B (self): def some_more_method(self): print("Let see here")

Details: Let's say you want to use method/function from class B in class A.

'Add this line' B.some_more_method(self)

It works for me.

Upvotes: 0

confusionm
confusionm

Reputation: 59

Update Managed to solve the problem.

Looking at the error I noticed that every time, the function change_screen is executed (due to a not-valid E-Mail format), it will run the following line in change_screen:

screen_manager = self.root.ids['screen_manager']

The problem was, that self.root was referring to the InsertData class, which does not have the attributes. Since self.roots refers to the GUI in the MainApp class, I changed the line in the change_screen function as follows:

screen_manager = GUI.ids['screen_manager']

Now the function is referring to the fixed GUI instead of the self.root and is running without any problems.

Upvotes: 0

user12574522
user12574522

Reputation:

This is how you can call function x for class B

 class A:
        def __init__(self):
            pass
        def x(self):
            print('x')

 class B:
        def __init__(self):
            A().x()

Upvotes: 1

Related Questions