Tkinter Digital Clock (Python)

vegaseat 2 Tallied Votes 26K Views Share

This short Python code gets the local time from the PC as a formatted string using time.strftime('%H:%M:%S'). The time string is displayed in a label using a larger font. A recursive function checks the time five times per second, and updates the time string, if it has changed. Five times per second may sound like overkill, but keeps the display from acting spasmodic.

# use Tkinter to show a digital clock
# tested with Python24    vegaseat    10sep2006

from Tkinter import *
import time

root = Tk()
time1 = ''
clock = Label(root, font=('times', 20, 'bold'), bg='green')
clock.pack(fill=BOTH, expand=1)

def tick():
    global time1
    # get the current local time from the PC
    time2 = time.strftime('%H:%M:%S')
    # if time string has changed, update it
    if time2 != time1:
        time1 = time2
        clock.config(text=time2)
    # calls itself every 200 milliseconds
    # to update the time display as needed
    # could use >200 ms, but display gets jerky
    clock.after(200, tick)

tick()
root.mainloop(  )
Aggressive.Panda 0 Newbie Poster

Why compare time2 and time1 when you can just directly call clock.after(200,tick)? It will update time anyways. I tried it and it worked.

woooee 814 Nearly a Posting Maven

The smallest time displayed is seconds. The function is called every 2/10 of a second, so the clock is not updated if the time to the second has not changed.

Aggressive.Panda 0 Newbie Poster

Okay.I am new,and I don't understand things fast, so please bear with me. What I meant to say was, why is time comparision b/w time1 and time2 required? If you just call the function every 2/10 of a second, time2 = time.strftime("%H:%M:%S:") time2, is itself getting updated every 2/10 of a second and clock.config(text=time2) will display that. There is no use of time1 here.
This is what I mean:

from Tkinter import *
import time
root = Tk()

clock = Label(root, font=('times', 20, 'bold'), bg='green')
clock.pack(fill=BOTH, expand=1)
def tick():
# get the current local time from the PC
    time2 = time.strftime('%H:%M:%S')
# if time string has changed, update it
    clock.config(text=time2)
# calls itself every 200 milliseconds
# to update the time display as needed
# could use >200 ms, but display gets jerky
    clock.after(200, tick)
tick()
root.mainloop( )

It will work the same way the given code is working.

TrustyTony 888 pyMod Team Colleague Featured Poster

That is because unnecessary update of the screen weakens the quality of the display. Maybe not, or only with slower computer, but it is good practice to avoid unnecessary refresh. Especially when you do more action on screen than just changing number.

Gribouillis 1,391 Programming Explorer Team Colleague

Here is a perhaps more readable version

try: from Tkinter import *
except ImportError: from tkinter import *
import time

root = Tk()
clock = Label(root, font=('times', 20, 'bold'), bg='green')
clock.pack(fill=BOTH, expand=1)

def tick():
    s = time.strftime('%H:%M:%S')
    if s != clock["text"]:
        clock["text"] = s
    clock.after(200, tick)

tick()
root.mainloop()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

When Python3 came around I updated much of my Tkinter code samples. So I looked back and this is what I did with the tk_clock ...

''' tk_clock101.py
use Tkinter to show a digital clock
tested with Python27 and Python33
'''

import time
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def tick(time1=''):
    # get the current local time from the PC
    time2 = time.strftime('%H:%M:%S')
    # if time string has changed, update it
    if time2 != time1:
        time1 = time2
        clock.config(text=time2)
    # calls itself every 200 milliseconds
    # to update the time display as needed
    clock.after(200, tick)

root = tk.Tk()
clock = tk.Label(root, font=('times', 20, 'bold'), bg='green')
clock.pack(fill='both', expand=1)
tick()
root.mainloop()

Almost 8 years have gone by since the original code. The speed of graphics chips has much improved, but it is still prudent not to stress the display unnecessarily, as pyTony has pointed out. The somewhat embarrasing global is gone too.

There is always a better mouse trap, so please improve the code as needed.

Aggressive.Panda 0 Newbie Poster

Thanks PyTony, Gribouillis and vegaseat. I now know why that was done so.

James_77 0 Newbie Poster

Hi All,

How do you think you can build a clock that shows the time in another country?

For example If I'm in the uk and I want to see the time in spain?

James

Gribouillis 1,391 Programming Explorer Team Colleague

@James_77 I would try to use the timezone data available in the dateutil module, for example

>>> import dateutil.tz
>>> from datetime import datetime
>>> spain = dateutil.tz.gettz(name='CET')
>>> d = datetime(2017, 3, 15, 17, 14, tzinfo = spain)
>>> d.utctimetuple()
time.struct_time(tm_year=2017, tm_mon=3, tm_mday=15, tm_hour=16, tm_min=14, tm_sec=0, tm_wday=2, tm_yday=74, tm_isdst=0)
>>> d.utcoffset()
datetime.timedelta(0, 3600)

There may be some more work involved, because in summer, Madrid uses CEST instead of CET for example.

Christopher_25 0 Newbie Poster

@vegaseat I much enjoyed your code here, but without a global variable for time1, your conditional statement will always execute (time1 is always set as an empty string when tick is called, so time1 != time2 is always true), defeating its purpose.

I recoded it with time1 as a parameter in line 14, initially set as an empty string in line 28, then as the argument for succesive calls in line 23.

# 14.    def tick(time1):
# 23.        clock.after(200,tick(time1))
# 28     tick("")

I am new to posting here, I hope I did so correctly.

hamed_4 0 Newbie Poster

hi guys
what is root.mainloop() doing in last line?

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

GUI (Graphics User Interface) programs use a loop to check and update the information the program receives. With tkinter the loop is called mainloop.

Vinay_17 0 Newbie Poster

I just wrote a version of myself and it's working just fine for me

import time
from tkinter import *
top=Tk()
c=Label(top,bg="green")
c.grid(row="0",column="0")
def ck():
          a = time.localtime(time.time())
          c.configure(text="%s:%s:%s" % (a.tm_hour, a.tm_min, a.tm_sec))
          c.after(1000,ck())
ck()
top.mainloop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.