Kivy更新动态标签文本

时间:2017-05-09 18:22:42

标签: properties label kivy

我的目标是观察Popup上的号码数量。我正在加载NumericProperty。但是,调用回调时,数字不会更改。 (我没有回调链接到label.text的任何代码)

有人问过类似的问题。但是,我一直无法看到它们如何适用于这个具体案例。 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()

2 个答案:

答案 0 :(得分:3)

您错过了一个事件,该事件会更新您需要在scoreLabel中处理的MyClass的文字值,请参阅下文:

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

当属性a更新时,on_a被触发,然后您可以使用它来更新scoreLabel值,否则它不会连接的。 text = str(ins.a)行从ins.a获取并为您使用0

但是,您需要以某种方式访问​​scoreLabel,这可能是有用的,例如: App.get_running_app()您可以在其中存储实例以供以后使用:

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

    content.add_widget(app.scoreLabel)

这样即使在on_a事件之后,您也可以访问它。或者使用self并使用Popup直接访问App.get_running_app().popup,然后再访问其内容。

App.get_running_app()有时候可能不是一个更好的选择,因此您可以使用偶数全局变量或其他方式来存储实例,例如在其他一些班级里面。如果您有Popup,则该小部件会将其自身添加到根Window,例如它存储在:

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

但要小心,因为直接搞乱Window可能会产生不幸的结果。

答案 1 :(得分:2)

我会采取不同的方法。
而不是使用全局变量,将得分作为自定义布局中的属性,并将其传递给弹出窗口。

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()