I am working on making a kivy app and have run into a problem where I can't update a label. I'm not sure where to go from here, but I want the date value to be displayed by a label in Class ThirdMenu. Here is all of my code, it is a bit disorganized. I am new to kivy and have not completely grasped all of the concepts so there are most likely many mistakes.
This is the class with the label I want to change:
class ThirdMenu(Screen, FloatLayout, EventDispatcher):
theme_cls = ThemeManager()
pickers = None
previous_date = ''
a = NumericProperty(0)
def __init__(self, **kwargs):
super(ThirdMenu, self).__init__(**kwargs)
global Date
#Labels
app = App.get_running_app()
app.D = Label(text=str(app.a),bold = True,text_size=(None,None),font_size="30sp",pos_hint={'center_x': 0.50, 'y': .8},size_hint_y=None,size = self.size,color=(1, 0, 0, 1))
self.add_widget(app.D)
#Buttons
FBBtn = Button(text ='Back to menu', size_hint =(1, .15), pos_hint ={'x': 0, 'y': 0.85})
self.add_widget(FBBtn)
FBBtn.bind(on_press = self.change_screen_menu)
Builder.load_string(KV)
self.pickers = Factory.Pickers()
self.add_widget(self.pickers)
#Screen manager / changing screens route
def change_screen_menu(self, *args):
self.manager.transition = SlideTransition(direction ='down')
self.manager.current = 'menu'
print('Screen is: ' + str(self.manager.current))
def on_a(self, instance, value):
app = App.get_running_app()
app.D.text = str(a)
print (a)
The KV string that loads in this class:
KV = """
<Pickers@Screen>
name: 'pickers'
BoxLayout:
orientation: 'vertical'
spacing: dp(20)
pos_hint: {'center_x': .5, 'center_y': .5}
size_hint_y: None
height: self.minimum_height
MDRaisedButton:
text: "Open date picker"
pos_hint: {'center_x': .5}
opposite_colors: True
on_release: app.show_example_date_picker()
MDLabel:
id: date_picker_label
theme_text_color: 'Primary'
halign: 'center'
Label:
id: Date
theme_text_color: 'Primary'
halign: 'center'
BoxLayout:
size_hint: None, None
size: self.minimum_size
pos_hint: {'center_x': .5}
Label:
theme_text_color: 'Primary'
text: "Start on previous date"
size_hint_x: None
width: self.texture_size[0]
color: 0, 0, 0, 0
MDCheckbox:
id: date_picker_use_previous_date"""
and then my main class with the function to change the date value:
class MyApp(App):
theme_cls = ThemeManager()
pickers = None
previous_date = ''
a = StringProperty(0)
def build(self):
Window.size = (750,1334)
Window.clearcolor = (1, 1, 1, 1)
#set up of screen manager
sm = ScreenManager()
#Adding the different screens
sm.add_widget(MainMenu(name='menu'))
sm.add_widget(MainApp(name='main'))
sm.add_widget(SecondMenu(name='second'))
sm.add_widget(ThirdMenu(name='third'))
sm.add_widget(FourthMenu(name='fourth'))
sm.add_widget(TinaMenu(name='tinamenu'))
sm.add_widget(JohnMenu(name='johnmenu'))
#Activating the screen manager
return sm
def show_example_date_picker(self, *args):
self.pickers = Factory.Pickers()
if self.pickers.ids.date_picker_use_previous_date.active:
pd = self.previous_date
try:
MDDatePicker(self.set_previous_date, pd.year, pd.month, pd.day).open()
except AttributeError:
MDDatePicker(self.set_previous_date).open()
else:
MDDatePicker(self.set_previous_date).open()
def set_previous_date(self, date_obj):
global a
app = App.get_running_app()
self.previous_date = date_obj
self.pickers.ids.date_picker_label.text = str(date_obj)
app.a = self.pickers.ids.date_picker_label.text
print(app.a)
ThirdMenu.text = str(app.a)
Thank you for reading, I really appreciate it.
Several strange things going on in your code:
ThirdMenu
class does not need to extend all those classes. Just extending Screen
is enough since Screen
is already a RelativeLayout
and an EventDispatcher
.Pickers
class extends Screen
, but you are not using it as a Screen
. You can just extend RelativeLayout
insteadself.pickers = Factory.Pickers()
in two different places. That gives you two different, unrelated instances of the Pickers
class. Making changes to the Pickers
instance that you create in the MyApp
class will have no effect on the Pickers
instance that is displayed in ThirdMenu
. You can use something similar to point #5, below, to access the correct instance of Pickers
in the show_example_date_picker()
metod.set_previous_date()
method you use app = App.get_running_app()
, but in that method self
is the app.And finally, in your set_previous_date()
method, you can set the label text with
self.root.get_screen('third').pickers.ids.Date.text = str(date_obj)
This accesses the root
of the App
, which is the ScreenManager
, then gets the Screen
with the name third
(ThirdScreen
), then accesses the pickers
attribute of ThirdScreen
, then accesses the ids
dictionary of Pickers
, from which it accesses the Date
(the Label
within Pickers
), and sets the text
attribute of that Label
to the picked date.