Reputation: 59
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
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
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
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