I need to reference the variable name_input
in TalkBot
screen. Here is the code:
import kivy
kivy.require('2.2.1')
import pyttsx3
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.uix.video import Video
from kivy.uix.image import Image
from kivy.uix.textinput import TextInput
from kivymd.uix.button import MDRaisedButton
from kivymd.uix.label import MDLabel
class homeScreen(Screen):
def __init__(self, **kwa):
super().__init__(**kwa)
#bacgkround gradient
bgbox = MDBoxLayout()
bgbox.add_widget(Image(source='background.png', allow_stretch=True, keep_ratio=False, size_hint_y=1))
self.add_widget(bgbox)
#page title
topic = MDLabel(text="Personal Information", font_style="H4", pos_hint = {'x': 0.03, 'y': 0.45})
topic_info = MDLabel(text="Please input the following information. This will be used to generate your report", font_style="H6", pos_hint = {'x':0.06, 'y':0.37})
#name input
name_prompt = MDLabel(text="Name:", pos_hint = {'x': 0.1, 'y': 0.3}, _text_color_str="white")
name_input = TextInput(size_hint_x = 0.3, size_hint_y = 0.05, pos_hint = {'x':0.1, 'y': 0.73}, multiline = False) #I want to reference this variable in talkbot screen
self.add_widget(topic)
self.add_widget(topic_info)
self.add_widget(name_prompt)
self.add_widget(name_input)
class TalkBot(Screen):
def __init__(self, **kwa):
super(TalkBot, self).__init__(**kwa)
hs = self.manager.get_screen('homeScreen') #need to reference here but the error
name = hs.name_input.text()
bgimg = Image(source="background.png", allow_stretch=True, keep_ratio=False, size_hint_y=1)
self.add_widget(bgimg)
def playvid(self):
bgvid = Video(source="speechvid.avi", allow_stretch=True, keep_ratio=False, size_hint_y=1, state="play")
box.add_widget(bgvid)
engine=pyttsx3.init()
engine.say(f"Hello {name}, welcome to Mind Magic!")
print(name)
engine.runAndWait()
btn = MDRaisedButton(text="start", pos_hint={'x':0.49, 'y':0.49}, on_release=playvid)
self.add_widget(btn)
box=MDBoxLayout()
self.add_widget(box)
class MindMagic(MDApp):
def build(self):
self.theme_cls.material_style = "M3"
self._app_name = "MindMagic"
self.icon = "logo.png"
sm = ScreenManager(transition = FadeTransition())
sm.add_widget(winvid(name="winvid"))
sm.add_widget(homeScreen(name="homeScreen"))
sm.add_widget(TalkBot(name="talkbot"))
return sm
if __name__ == "__main__":
MindMagic().run()
I have tried some solutions, and logically I think self.manager.get_screen
should work. I have also tried MDApp.get_running_app().root
. But both throw the error AttributeError: 'NoneType' object has no attribute 'get_screen'
The kivy widget tree is not accessible at the time the objects get initialized. Your options are:
1. Move all operations that must acces the widget tree into a separate function and set it to execute on first render with Clock.schedule_once
:
class TalkBot(Screen):
def __init__(self, **kwa):
super(TalkBot, self).__init__(**kwa)
Clock.schedule_once(self.init)
def init(self, _):
hs = self.manager.get_screen('homeScreen') # need to reference here but the error
name = hs.name_input.text
bgimg = Image(source="background.png", allow_stretch=True, keep_ratio=False, size_hint_y=1)
self.add_widget(bgimg)
def playvid(self):
bgvid = Video(source="speechvid.avi", allow_stretch=True, keep_ratio=False, size_hint_y=1, state="play")
box.add_widget(bgvid)
engine = pyttsx3.init()
engine.say(f"Hello {name}, welcome to Mind Magic!")
print(name)
engine.runAndWait()
btn = MDRaisedButton(text="start", pos_hint={'x': 0.49, 'y': 0.49}, on_release=playvid)
self.add_widget(btn)
box = MDBoxLayout()
self.add_widget(box)
(Note that this was still crashing for me at first because name_input
is not assigned to an instance variable in homeScreen
and because the TextInput's text is an attribute and not a callable and you were using hs.name_input.text()
.)
2. Initialize TalkBot with self.name = None
, then set it to the homeScreen's current value whenever you do the screen transition:
class homeScreen(Screen):
...
def go_to_talkbot_screen(self):
self.manager.get_screen("talkbot").name = self.name_input.text
self.manager.current = "talkbot"