Reputation: 460
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()
Upvotes: 2
Views: 10336
Reputation: 5405
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()
Upvotes: 3
Reputation: 12169
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.
Upvotes: 4