Kivy Update Dynamic Label Text

给你一囗甜甜゛ 提交于 2019-12-11 04:46:56

问题


My goal is to watch the number count on the Popup. I have a NumericProperty being loaded. However, The numbers do not change when callback is called. (I do not have any code in callback linking to the label.text)

Similar questions have been asked. But, I have been unable to see how they apply to this specific case. Similar Case

import kivy
kivy.require("1.7.0")

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.properties import NumericProperty
from kivy.clock import Clock
from kivy.event import EventDispatcher

scoreInc = 0

class MyPopup(Popup):

    def show_popup(self):

        content = BoxLayout(orientation="vertical")

        self.incrementerFnc = Clock.schedule_interval(self.incrementer, .005)

        scoreLabel = Label(text=str(ins.a), id='scorelabel', font_size=20)

        content.add_widget(scoreLabel)

        mybutton = Button(text="Close", size_hint=(1,.20), font_size=20)
        content.add_widget(mybutton)

        mypopup = Popup(content = content,              
                title = "Score",     
                auto_dismiss = False,         
                size_hint = (.7, .5),         
                font_size = 20)
        mybutton.bind(on_press=mypopup.dismiss)  
        mypopup.open()

    def incrementer(self, dt):
        global scoreInc
        scoreInc += 1

        ins.a = scoreInc

        if(scoreInc >= 10):
            Clock.unschedule(self.incrementerFnc)
            print('quit')
        else:
            print('scoreInc', ins.a)    

class MyClass(EventDispatcher):
    a = NumericProperty(0)

def callback(instance, value):
    print('My callback is call from', instance)
    print('and the a value changed to', value)

ins = MyClass()
ins.bind(a=callback)


class MyApp(App):     

    def build(self):

        mypopup = MyPopup()

        return mypopup.show_popup()

if __name__ == "__main__":
    MyApp().run()

回答1:


You are missing an event that updates the text value of your scoreLabel which you need to handle in your MyClass, see below:

class MyClass(EventDispatcher):
    a = NumericProperty(0)
    def on_a(self, instance, value):
        app = App.get_running_app()
        app.scoreLabel.text = str(value)

when property a updates, on_a is triggered and then you can use it to update the scoreLabel value, otherwise it's not even connected. The line text = str(ins.a) takes the value from the ins.a and uses it i.e. 0 for you.

However, you'll need to access that scoreLabel somehow, which might be useful through e.g. App.get_running_app() where you can store the instance for later use:

    app = App.get_running_app()
    app.scoreLabel = Label(text=str(ins.a), id='scorelabel', font_size=20)

    content.add_widget(app.scoreLabel)

This way you can access it even in the on_a event later. Or use self and access the Popup directly with App.get_running_app().popup and then its content.

App.get_running_app() however might be not a preferable option sometimes, therefore you can use even globals, or some other way to store the instance e.g. inside some other class. If you have a Popup, that widget adds itself to the root Window for example and it's stored in:

Window -> children -> Popup -> content -> layout -> scoreLabel

but be careful with that because messing with the Window directly might have unfortunate results.




回答2:


I would take a different approach at this.
Instead of using globals, have the score as a property in a custom layout, and pass that to the popup.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock


KV = '''

<MyPopup>:
    title: "Game over"
    score_label: score_label
    id: popup
    content: bl
    BoxLayout:
        id: bl
        Label:
            id: score_label
            text:"Your score is"
            font_size:20
        Button:
            text:"Close this!!"
            on_release: popup.dismiss()


MyLayout:

    orientation: "vertical"
    Label:
        text: "Type in score"
    TextInput:
        id: score_inp
    Button:
        text: "Open gameover popup"
        on_release:
            root.gameover_popup.open()
            root.gameover_popup.gameover(score_inp.text)

'''


class MyPopup(Popup):

    def gameover(self,score):
        self.iterations = int(score)
        self.score = 0
        self.event = Clock.schedule_interval(self.set_label,0.1)

    def set_label(self,dt):
        self.score += 1
        self.score_label.text = str(self.score)
        if self.score >= self.iterations:
            self.event.cancel()



class MyLayout(BoxLayout):

    def __init__(self,**kwargs):
        super(MyLayout,self).__init__(**kwargs) 
        self.gameover_popup = MyPopup()



class MyApp(App):

    def build(self):
        return Builder.load_string(KV)


MyApp().run()


来源:https://stackoverflow.com/questions/43877241/kivy-update-dynamic-label-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!