I'm trying to update the value of a label in 2 widgets and a screen. This should be pretty straightforward but I haven't been able to make it work!
I suspect that whatever I'm doing is not being picked up by the GUI for some reason. I say this because when "printing values" to debug the value does update as expected.
Finally, I've looked at several solutions but neither seem to work: Kivy Label Text does not update, Kivy: Label text does not update during for-loop, Kivy Label.text Property doesn't update on the UI
The screen I'm trying to update:
Screens/recipe_screen.py
from kivymd.uix.screen import MDScreen
class RecipeScreen(MDScreen):
pass
Screens/recipe_screen.kv
#:import CounterWidget Components.counter_widget.CounterWidget
#:import IngredientsLabel Components.ingredients_label.IngredientsLabel
<RecipeScreen>:
name: 'recipe_screen'
id: recipe_screen
MDBoxLayout:
adaptive_height: True
orientation: 'horizontal'
padding: 30, 20
spacing: 0
IngredientsLabel:
id: il
label_text: 'text I'm trying to update'
CounterWidget:
Widget 1: this is what I'm calling from the GUI
components/counter_widget.py
from kivymd.uix.card import MDCard
from Components.ingredients_label import IngredientsLabel
class CounterWidget(MDCard):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.counter = 4
def increase_widget(self):
self.counter += 1
self.ids['counter_text'].text = str(self.counter) <--- THIS WORKS FINE
ingredient_label_ref = IngredientsLabel
ingredient_label_ref().change_label(self.counter) <--- THIS DOES NOT WORK
components/counter_widget.kv
#:import RecipeScreen Screens.recipe_screen.RecipeScreen
<CounterWidget>:
elevation: 5
border_radius: 15
radius: [15]
size_hint: None, None
size: 250, 90
MDGridLayout:
MDLabel:
id: counter_text
text: '4'
Widget 2: this is the widget I'm trying to update based on Widget 1
components/ingredients_label.py
from kivymd.uix.boxlayout import MDBoxLayout
class IngredientsLabel(MDBoxLayout):
def change_label(self, counter):
self.ids['servings_counter'].text = str(counter) + ' servings' <--- DOES NOT UPDATE GUI
print('IngredientsLabel: ' + str(counter) + ' servings') <--- PRINTS CORRECTLY IN TERMINAL
components/ingredients_label.kv
#:import RecipeScreen Screens.recipe_screen.RecipeScreen
<IngredientsLabel>:
adaptive_height: True
orientation: 'vertical'
MDLabel:
id: servings_counter
markup: True
text: '4 servings'
font_style: 'Subtitle2'
main.py
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.factory import Factory
from kivy.uix.screenmanager import ScreenManager
from Screens.recipe_screen import RecipeScreen
from Screens.carousel_screen import CarouselScreen
class MainApp(App, MDApp):
def build_app(self):
Window.size = [350, 560]
sm = ScreenManager()
sm.add_widget(RecipeScreen(name='recipe_screen'))
sm.add_widget(CarouselScreen(name='carousel_screen'))
return sm
if __name__ == '__main__':
MainApp().run()
Update post @John Anderson suggestion to:
def increase_widget(self):
self.counter += 1
self.ids['counter_text'].text = str(self.counter)
ingredient_label_ref = MDApp.get_running_app().root.get_screen('recipe_screen').ids.il # get reference to IngredientsLabel
ingredient_label_ref.change_label(self.counter)
Unfortunately, this didn't work either.
I also tried referencing in the .kv file via:
Changing the components/ingredients_label.kv to
#:import RecipeScreen Screens.recipe_screen.RecipeScreen
<IngredientsLabel>:
adaptive_height: True
orientation: 'vertical'
label_text: 'None'
MDLabel:
markup: True
text:'Ingredients for'
font_style: 'H6'
MDLabel:
markup: True
text: root.label_text
font_style: 'Subtitle2'
and components/counter_widget.py to (while keeping the 'il' id reference for the IngredientsLabel widget on the RecipeScreen)
from kivymd.uix.card import MDCard
from Components.ingredients_label import IngredientsLabel
class CounterWidget(MDCard):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.counter = 4
def increase_widget(self):
self.counter += 1
self.ids['il'].label_text = str(self.counter)
but this didn't work either (no error, but no update to the UI either...).
I included the App class above as well.
Without a complete runnable code (you have not provided an App
class), it is difficult to provide a definitive answer. However, assuming that your App
creates a ScreenManager
with RecipeScreen
as one of its Screens
, you can modify your increase_widget()
method:
def increase_widget(self):
self.counter += 1
self.ids['counter_text'].text = str(self.counter)
ingredient_label_ref = MDApp.get_running_app().root.get_screen('recipe_screen').ids.il # get reference to IngredientsLabel
ingredient_label_ref.change_label(self.counter)
In order for this to work, you must add some ids
to your kv
:
<RecipeScreen>:
name: 'recipe_screen'
id: recipe_screen
MDBoxLayout:
adaptive_height: True
orientation: 'horizontal'
padding: 30, 20
spacing: 0
IngredientsLabel:
id: il # added id
CounterWidget:
id: cw # added, but not required