Skip to content

Instantly share code, notes, and snippets.

@jbaber
Last active October 5, 2015 02:23
Show Gist options
  • Save jbaber/d13e42e26a58dc45e5f4 to your computer and use it in GitHub Desktop.
Save jbaber/d13e42e26a58dc45e5f4 to your computer and use it in GitHub Desktop.
How do I make user_layout.score a NumericProperty that calls update_bar ?
"""
How do I make the user bars change whenever the user scores
change?
"""
from __future__ import print_function
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
from kivy.lang import Builder
from kivy.properties import ObjectProperty, NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
import datetime
import random
import time
kv = """
<RootWidget@BoxLayout>:
info: info
the_main_box: the_main_box
BoxLayout:
id: the_main_box
on_parent: root.initial_setup()
Label:
id: info
"""
Builder.load_string(kv)
class UserLayout(BoxLayout):
score = NumericProperty(.5)
def on_score(self, instance, value):
RootWidget.update_bar(self.bar_label, value)
class RootWidget(BoxLayout):
the_main_box = ObjectProperty()
def initial_setup(self):
# Add dynamically created layouts
self.user_layouts = RootWidget.bare_user_layouts()
for layout in self.user_layouts:
self.the_main_box.add_widget(layout)
# Add scores (numbers in [0, 1)) to the layouts
# to be used to set the lengths of the bars
RootWidget.update_scores(self.user_layouts)
# Draw the labels
self.set_labels()
# Change the scores every second
# (set_labels doesn't take the argument the Clock would
# give it, hence the lambda being passed to it)
def scheduled_event(dt):
RootWidget.update_scores(self.user_layouts)
self.set_labels("\nScores: " +
str([float(str(user_layout.score)[0: 3])
for user_layout in self.user_layouts])
)
Clock.schedule_interval(scheduled_event, 3)
@classmethod
def update_scores(klass, user_layouts):
for layout in user_layouts:
layout.score = random.random()
def set_labels(self, extra_string=None):
"""
Set up lots of things in the labels.
"""
if not extra_string:
extra_string = ""
self.info.text = timestamp() + extra_string
@classmethod
def bare_user_layouts(klass):
"""
Return a list of user layouts
"""
# In real code, these are dynamically set, so can't know how
# many in advance.
users = ["Richard", "Gerald", "Jimmy"]
# Color for the bar for each user
hues = dict(zip(users, [0, .33, .66]))
to_return = []
for index, user in enumerate(users):
user_layout = UserLayout()
user_layout.user_name = user
# The label containing the horizontal bar for the user
user_bar_label = Label()
user_layout.bar_label = user_bar_label
user_bar_label.id = "bar_{0}".format(user)
# Add the bar (It's position and size won't matter yet
# but the color set here sticks)
with user_bar_label.canvas.before:
Color(hues[user], 1, 1, mode='hsv')
user_bar_label.rect = Rectangle()
# Change the bars whenever the screen is resized (pos and
# size) This apparently includes once initially added.
# user_bar_label.bind(pos=klass.update_bar,
# size=klass.update_bar)
# user_layout.on_score(klass.update_bar)
# Actually add the widget to the layout
user_layout.add_widget(user_bar_label)
# Add the layout to what will be returned
to_return.append(user_layout)
return to_return
@classmethod
def update_bar(klass, label, score):
"""
Change the length of the bar in `label` to respect `score`
"""
# Scale the height to match
label.rect.size = [label.size[0], label.size[1] * score]
label.rect.pos = label.pos
# Set the text to the time updated
label.text = timestamp()
def timestamp():
"""
Return Hour, minute, second string
"""
return datetime.datetime.now().strftime("%H:%M:%S.%f")
class BarebonesApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
BarebonesApp().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment