2017-05-09 1 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

당신은 당신이 당신의 MyClass에서 처리 할 필요가 당신의 scoreLabel의 텍스트 값을 업데이트하는 이벤트를 누락, 아래 참조 : 부동산 a 업데이트, on_a가 트리거

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

을 사용하면 scoreLabel 값을 업데이트 할 수 있습니다. 그렇지 않으면 연결되어 있지 않습니다. 줄 text = str(ins.a)ins.a에서 값이이고 그 값이 0입니다.

그러나 어쨌든 scoreLabel에 액세스해야합니다.

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

    content.add_widget(app.scoreLabel) 

이 방법 당신도 나중에on_a 이벤트에 액세스 할 수 있습니다 : 당신이 나중에 사용하기 위해 인스턴스를 저장할 수 있습니다 App.get_running_app(). 또는 self을 사용하고 App.get_running_app().popup으로 직접 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