I'm building a KivyMD application, but I'm having some issues to get a variable defined in one Screen class into another. See my script below:
from kivymd.app import MDApp, Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import StringProperty
from api import gen_5_images
# --- this changes the app's default background --- #
Window.clearcolor = (.9, .9, .9, 1)
Window.size = (400, 500)
class HomeScreen(Screen):
source = StringProperty()
def __init__(self, **kwargs):
super(HomeScreen, self).__init__(**kwargs)
self.text = 'dog'
def get_text(self):
self.text = self.ids.input.text
return self.text
class ResultsScreen(HomeScreen):
source = StringProperty()
def on_manager(self, *args):
# gets run when manager property is changed
self.urls = gen_5_images(self.manager.get_screen('home').text)
self.source = self.urls[0]
class Main(MDApp):
def build(self):
Builder.load_file("layout.kv")
sm = ScreenManager()
sm.add_widget(HomeScreen(name='home'))
sm.add_widget(ResultsScreen(name='results'))
return sm
Main().run()
When I switch from HomeScreen to ResultsScreen, I get the variable "dog" (defined in HomeScreen's init) as text, and I want the output of the "get_text" function instead.
See below my .kv file:
#:import hex kivy.utils.get_color_from_hex
<HomeScreen>:
name: 'home'
MDFloatLayout:
md_bg_color: hex('#003153') # background color
MDLabel:
text: "DreamGen"
color: hex('#f5deb3')
halign: "center"
pos_hint: {"center_x": .5, "center_y": .9}
font_size: "40sp"
font_name: "Pacifico"
MDTextField:
id: input
hint_text: "I had a dream..."
hint_text_color_normal: hex("#00aae4")
hint_text_color_focus: hex("#00aae4")
helper_text_color_focus: hex("#00aae4")
line_color_normal: hex('#003153') #make line color of background
line_color_focus: hex('#003153') #make line color of background
helper_text: "Write what comes to your mind"
helper_text_mode: "on_focus"
text_color_focus: hex('#add8e6') # color of text clicked
text_color_normal: hex('#add8e6') # color of text without clicked
mode: "rectangle"
multiline: True
size_hint_x: 0.7
size_hint_y: 0.5
pos_hint: {"center_x": .5, "center_y": .5}
MDFillRoundFlatButton:
text: "Generate"
text_color: hex('#003153')
md_bg_color: hex('#add8e6')
pos_hint: {"center_x": .5, "center_y": .1}
font_size: "15sp"
on_release:
root.get_text()
root.manager.current = "results"
<ResultsScreen>:
name: 'results'
MDFloatLayout:
md_bg_color: hex('#003153') # background color
MDLabel:
text: "DreamGen"
color: hex('#f5deb3')
halign: "center"
pos_hint: {"center_x": .5, "center_y": .9}
font_size: "40sp"
font_name: "Pacifico"
AsyncImage:
size_hint: None,None
size: root.height, root.height
source: root.source
mipmap: True
MDFillRoundFlatButton:
text: "Try again!"
text_color: hex('#003153')
md_bg_color: hex('#add8e6')
pos_hint: {"center_x": .5, "center_y": .1}
font_size: "15sp"
on_release: root.manager.current = "home"
If someone can help me, I would very much appreciate.
Your code:
self.urls = gen_5_images(HomeScreen().text)
is creating a new instance of HomeScreen
and accessing the text
variable of that new instance. That new instance of HomeScreen
is not the instance that is used in your GUI. To access the correct instance of HomeScreen
, try changing that code to:
self.urls = gen_5_images(self.manager.get_screen('home').text)
Oops, that code will work, but not in the __init__()
method, since the manager
property is not yet set at that time. You can handle that by waiting until the manager
property is set. Try replacing:
class ResultsScreen(HomeScreen):
source = StringProperty()
def __init__(self, **kwargs):
super().__init__()
self.urls = gen_5_images(HomeScreen().text)
self.source = self.urls[0]
with:
class ResultsScreen(HomeScreen):
source = StringProperty()
# def __init__(self, **kwargs):
# super().__init__()
# # self.urls = gen_5_images(HomeScreen().text)
# # self.source = self.urls[0]
def on_enter(self, *args):
# gets run each time this Screen is displayed
self.urls = gen_5_images(self.manager.get_screen('home').text)
self.source = self.urls[0]