简体   繁体   中英

How can I make my Kivy Label update dynamically when a value is changed?

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.

As long as you have the label id, you can change its value on the main file.

(...)

Label:
            id: Date
            theme_text_color: 'Primary'
            halign: 'center'

(...)

On main.py (...)

def change_date(newValue):    
            self.Date = newValue

(...)

Several strange things going on in your code:

  1. ThirdMenu class does not need to extend all those classes. Just extending Screen is enough since Screen is already a RelativeLayout and an EventDispatcher .
  2. Your Pickers class extends Screen , but you are not using it as a Screen . You can just extend RelativeLayout instead
  3. You are using self.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.
  4. In your set_previous_date() method you use app = App.get_running_app() , but in that method self is the app.
  5. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM