Trying to make a clock app

31 views
Skip to first unread message

Abraham Francisco

unread,
Mar 27, 2020, 9:36:51 AM3/27/20
to Kivy users support
Trying to adjust my code to where the time shows up on the app and it real-time updates. But at first it only showed a static time stamp but now, after trying to utilize "Clock.schedule_interval" I get a on screen representation of an object that doesnt do or represent anything. Any help would be appreciated! Code below and yal stay safe and indoors out there.

Yes, I am a beginner.

from time import sleep, strftime
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.clock import Clock
import os



def t1(*args):
while True:
t = strftime("%I:%M:%S %p")
sleep(1)
return t



class ClockPage(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)

self.label = Label()

self.add_widget(Label(text=str(Clock.schedule_interval(t1, 1))))



class MainApp(App):
def build(self):
return ClockPage()


if __name__ == "__main__":
MainApp().run()

Elliot Garbus

unread,
Mar 27, 2020, 11:37:45 AM3/27/20
to kivy-...@googlegroups.com

Try this.  Note the comments.

 

 

from time import strftime
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock

kv =
"""
BoxLayout:
    MyClock:
        font_size: 50
        id:my_clock

"""

# def t1(*args):     # You can not have this kind of endless loop.  Use clock to schedule time.
#     while True:
#         t = strftime("%I:%M:%S %p")
#         sleep(1)                              # Never use sleep
#         return t


class MyClock(Label):
   
pass


class
MainApp(App):
   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):                   # This is a builtin method of app called at the start, after build.
       
t = strftime("%I:%M:%S %p")
       
self.root.ids.my_clock.text = t
        Clock.schedule_interval(
self.update_time, 1)

   
def update_time(self, dt):            # The call back function to update the time
       
t = strftime("%I:%M:%S %p")
       
self.root.ids.my_clock.text = t


--
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/3e273b70-3c53-455f-809f-187ca9b48f2f%40googlegroups.com.

 

Abraham Francisco

unread,
Mar 28, 2020, 11:13:13 AM3/28/20
to Kivy users support
What does "dt" mean in the update_time function?

It worked wonderfully btw! Just trying to figure out why now.

So tell me if I'm wrong:

Kivy builds and loads on screen the kv formatted string, which houses in a layout of the empty class "MyClock?" It does this just to adopt its Label functionalities?

An id is set to be able to reference back to it from the on_start function, which initially sets the time and schedules an interval update through use of the update_time function.

Couple questions if I'm understanding the above, what's going on in the code line, "self.root.ids.my_clock.text = t"? In particular the 'root.ids" part.

And lastly, so I'm assuming all the functions in MainApp just run automatically if name = main, but wouldn't that mean the function update_time would get run twice because of the callback in on_start as well as the initial run?

All in all, thank you so much for your gracious help!

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

Elliot Garbus

unread,
Mar 28, 2020, 11:52:15 AM3/28/20
to kivy-...@googlegroups.com

What does "dt" mean in the update_time function?

https://kivy.org/doc/stable/api-kivy.clock.html?highlight=clock#module-kivy.clock

dt shows the amount of time that has elapsed.  We requested a call every second, dt shows the actual time.  Print it out.

 

So tell me if I'm wrong:

 

Kivy builds and loads on screen the kv formatted string, which houses in a layout of the empty class "MyClock?" It does this just to adopt its Label functionalities?

 

Yes.  In fact in the example you can just replace MyClock in kv with Label and remove the MyClock definition from python.  I must have thought I was gong to put the code into MyClock – but I put it in app instead.  More generally, you will inherit from widgets or layouts, and extend them to create your application.

 

An id is set to be able to reference back to it from the on_start function, which initially sets the time and schedules an interval update through use of the update_time function.

 

Correct.  You specify an id in kv.  During build() the kv code is parsed.  The id’s become keys in a dictionary called ids.  The key (the id) has an associated value of the widget.  https://kivy.org/doc/stable/api-kivy.lang.html?highlight=lang#ids

 

Couple questions if I'm understanding the above, what's going on in the code line, "self.root.ids.my_clock.text = t"? In particular the 'root.ids" part.

 

You can print each of these parts to see what they are.  Because we are in a class derived from App.  Self refers to the App,

Root refers to the root widget (a BoxLayout) ids is a dictionary of id’s.  my_clock is one of the id’s, and points to the MyClock Label widget.  Putting it all together: self.root.ids.myclock.text is referring to the text of the MyClock label.

From on_start print out each of the pieces: self, self.root, self.root.ids…

 

And lastly, so I'm assuming all the functions in MainApp just run automatically if name = main, but wouldn't that mean the function update_time would get run twice because of the callback in on_start as well as the initial run?

 

Update time will only be run when it is called from Clock.schedule_interval().  The def keyword in python denotes a function or method (a function that is part of a class).  This creates a callable object on the initial ‘run’, it is not executed until it is called.  In this example update_time is only called from Clock.schedule_interval().  Add a print statement to update_time() to see for yourself.

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/0f3ca2c2-14d4-448f-9cb9-2ee565471252%40googlegroups.com.

 

Elliot Garbus

unread,
Mar 28, 2020, 12:22:03 PM3/28/20
to kivy-...@googlegroups.com

Here is an alternative implementation, that uses MyClock:

 

from time import strftime
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.properties import StringProperty

kv =
"""
BoxLayout:
    MyClock:
        font_size: 50
        text: self.current_time
"""


class MyClock(Label):
    current_time = StringProperty(strftime(
"%I:%M:%S %p"))

   
def __init__(self, **kwargs):
        Clock.schedule_interval(
self.update_time, 1)
       
super().__init__(**kwargs)

   
def update_time(self, dt):
       
self.current_time = strftime("%I:%M:%S %p")


class MainApp(App):
   
def build(self):
       
return Builder.load_string(kv)


Abraham Francisco

unread,
Mar 29, 2020, 10:13:29 AM3/29/20
to kivy-...@googlegroups.com
Wow! Thank you so much! This all makes very much sense now! I'll definitely read up on the documentation more thoroughly for the next step. lol 

Thanks and stay safe out there.

Reply all
Reply to author
Forward
0 new messages