Share some code.
It looks like the problem is the callback function, not the time.
--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/53938d4d-9316-4898-ac77-c8b369b77943%40googlegroups.com.
Here is a working example:
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.core.audio import SoundLoader
import datetime
kv = """
BoxLayout:
Label:
text: 'Sound Every Minute'
font_size: 50
"""
class TimeToMinApp(App):
def __init__(self, **kwargs):
self.sound = SoundLoader.load('music\iterate-040.wav')
super().__init__(**kwargs)
def build(self):
return Builder.load_string(kv)
def on_start(self):
Clock.schedule_once(self.next_min, self.seconds_to_minute())
print(f'seconds to minute: {self.seconds_to_minute()}')
def next_min(self, dt):
self.sound.play()
Clock.schedule_interval(self.play_chime, 60)
def play_chime(self, dt):
self.sound.play()
@staticmethod
def seconds_to_minute():
now = datetime.datetime.now()
next_min = now.replace(microsecond=0, hour=0, second=0) + datetime.timedelta(minutes=1)
return (next_min - now.replace(hour=0)).total_seconds()
TimeToMinApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5ec28dae.1c69fb81.6a24f.3747SMTPIN_ADDED_MISSING%40gmr-mx.google.com.
I added a little test – and see I am off by one second. I haven’t taken the time to see why…
I added a second to the wait time.
I’m reminded of a joke:
The 2 hardest problems in computer science are: Memory Leaks, Race Conditions, and off by one problems
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.core.audio import SoundLoader
from kivy.properties import StringProperty
import datetime
kv = """
BoxLayout:
orientation: 'vertical'
Label:
text: 'Sound Every Minute'
font_size: 50
Label:
text: 'Chime Time: ' + app.chime_time
"""
class TimeToMinApp(App):
chime_time = StringProperty('Time of Chime')
def __init__(self, **kwargs):
self.sound = SoundLoader.load('music\iterate-040.wav')
super().__init__(**kwargs)
def build(self):
return Builder.load_string(kv)
def on_start(self):
Clock.schedule_once(self.next_min, self.seconds_to_minute())
def next_min(self, dt):
self.sound.play()
Clock.schedule_interval(self.play_chime, 60)
self.chime_time = str(datetime.datetime.now())
def play_chime(self, dt):
self.sound.play()
now = datetime.datetime.now()
print(now)
self.chime_time = str(now)
@staticmethod
def seconds_to_minute():
now = datetime.datetime.now()
next_min = now.replace(
microsecond=0, hour=0, second=0) + datetime.timedelta(minutes=1)
return (next_min - now.replace(hour=0)).total_seconds() + 1
TimeToMinApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5ec2ab38.1c69fb81.909c9.00a7SMTPIN_ADDED_MISSING%40gmr-mx.google.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5ec28dae.1c69fb81.6a24f.3747SMTPIN_ADDED_MISSING%40gmr-mx.google.com.
Summary of changes, move most of the attributes to be instance variables, rather than class variables
The problem you were experiencing was caused by setting the NumericProperty Timer to Clock.schedule_interval()
I changed the second use of timer to self.one_second_timer.
class clockLabel(Label):
current_time = StringProperty(strftime('%H:%M:%S'))
timer = NumericProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.sound = SoundLoader.load('bell.mp3')
self.curr_min = int(strftime('%M'))
self.curr_sec = int(strftime('%S'))
self.next_call = self.curr_min + 1
self.timer = self.time_left = 60 - self.curr_sec
print("time is:", strftime('%H:%M:%S'))
print("minutes", self.curr_min)
print("seconds", self.curr_sec)
self.one_second_timer = Clock.schedule_interval(self.update_time, 1) # This was the problem
self.ticker = Clock.schedule_interval(self.ring_bell, self.timer)
# self.ticker = Clock.schedule_interval(self.ring_bell, time_left)
def update_time(self, dt):
self.current_time = strftime('%H:%M:%S')
def ring_bell(self, dt):
print("BOING")
self.sound.play()
def cancel_time(self):
self.one_second_timer.cancel()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/CAMk%2Bs2RZ1UPv0MDmMcF402naZQmxWx%3Dhc6nME1mJBJtaS%2B%3DUMg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5ec30379.1c69fb81.1bf4a.1a0eSMTPIN_ADDED_MISSING%40gmr-mx.google.com.
Code below.
The `ring_bell` function is called twice each time
You were instancing the kv code twice. You have a root widget in the kv file, and were instancing the root widget in python. This is fixed in the code below.
The update does not go in sync every minute; I think I will have to work on how to hold the horses until `00` is stuck and then re-launch the thing. Can I move the variables related to time into a Clock.schedule_interval?
In the code below you can see I have used a Clock.schedule_once to consume the time to the top of the minute, and then use Clock.schedule_interval() to ring the bell every minute. The method seconds to minute, calculates the number of seconds until the top of the hour. I have rounded the result to hundredths of a second.
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.core.text import LabelBase
from kivy.properties import StringProperty, NumericProperty
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.core.audio import SoundLoader
from time import strftime
import datetime
import os
# set sound env
# `python3 -m pip install ffpyplayer`
os.environ['KIVY_VIDEO'] = 'ffpyplayer'
class MyGrid(Widget):
pass
class ImageButton(ButtonBehavior, Image):
pass
class ClockLabel(Label):
current_time = StringProperty(strftime('%H:%M:%S'))
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.sound = SoundLoader.load('bell.mp3')
self.main_clock = Clock.schedule_interval(self.update_time, 1)
Clock.schedule_once(self.next_min, self.seconds_to_minute())
def update_time(self, dt):
self.current_time = strftime('%H:%M:%S')
def ring_bell(self, dt):
print(f'ring_bell: {strftime("%H:%M:%S")}')
self.sound.play()
def next_min(self, dt):
self.sound.play()
Clock.schedule_interval(self.ring_bell, 60)
print(f"first chime: {datetime.datetime.now()}")
@staticmethod
def seconds_to_minute():
now = datetime.datetime.now()
next_min = now.replace(
microsecond=0, hour=0, second=0) + datetime.timedelta(minutes=1)
return round((next_min - now.replace(hour=0)).total_seconds() + 1, 2)
def cancel_time(self):
self.main_clock.cancel()
def find_time(self):
pass
# to be defined, maybe a Clock.schedule_interval that set the time
class ClockApp(App):
pass
# def build(self):
# return MyGrid() # this causes 2 copies of the code to be instanced.
if __name__ == "__main__":
ClockApp().run()
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/CAMk%2Bs2TaeZMKW_nTF06PWwy393shSyQpjhtnFi83j3cfR9RVMg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/5ec548f7.1c69fb81.25213.33daSMTPIN_ADDED_MISSING%40gmr-mx.google.com.
You have a root widget in the kv file, and you are instancing the root widget in python. This causes 2 copies of the kv code to be used. This is why you see 2 print outs.
I hear a bell at every minute, but it is possible it is causing problems on your system.
class ClockApp(App):
# def build(self):
# return MyGrid()
pass
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/CAMk%2Bs2Rj5EV6Lj1QbLWUv1aj4wkA%2BKVqVdMWLLdw9hJ%2BVjABmg%40mail.gmail.com.
On Windows10, I hear a bell every minute. Just an idea, try to seek to the beginning of the sound file.
def update_time(self, dt):
self.current_time = strftime('%H:%M:%S'
)
self.curr_sec = int(strftime('%S'))
if self.curr_sec == 0:
print("time is:", strftime('%H:%M:%S'))
self.sound.play()
self.sound.seek(0)
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/CAMk%2Bs2SKMXv8gAJBEXM%3Da%3DZ8oVJ7Bc0J8QWcvi2tr9gz_SYckQ%40mail.gmail.com.