2017-05-09 159 views
1

我的目標是觀察Popup上的數量。我有一個NumericProperty正在加載。但是,當調用回調時,這些數字不會改變。 (我沒有任何回調鏈接到label.text的代碼)Kivy更新動態標籤文本

已經提出了類似問題。但是,我一直無法看到它們如何適用於這個特定案例。 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

你缺少一個更新您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 

但要小心,由於與窗口直接搞亂可能有不幸的結果。

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

這兩個答案都很完美。 – xxLITxx