我的目标是观察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()
答案 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()