You need to start the Tkinter mainloop. Just add
root.mainloop()
to the end of the script after your
showTime()
call.
The reason that your script works in IDLE is that IDLE itself is a Tkinter program, and it already has an event loop going as mentioned in this answer.
BTW, that if True:
statement in showTime
is pointless.
FWIW, here is your program with the mainloop call added, and a few other minor changes. It's better to avoid "star" imports because they clutter your namespace with the imported names, eg from tkinter import *
brings in over 130 names. This can cause collisions with names you define yourself, unless you're intimately familiar with every name that Tkinter defines, but it's especially problematic if you use a star import with another module that happens to use names that Tkinter uses.
import time
import tkinter as tk
def showTime():
canvas.delete('text')
actualTime = time.localtime()
text = canvas.create_text((100, 50),
text = actualTime[3:6],
fill="white",
font=("Verdana", 20, "bold"),
tag="text")
root.after(1000, showTime)
if "__main__" == __name__:
root = tk.Tk()
root.resizable(False,False)
root.title("Clock")
canvas = tk.Canvas(root, width=200, height=100, bg="black", cursor="target")
canvas.create_rectangle((20, 20), (180, 80), outline="ghostwhite")
canvas.pack()
showTime()
root.mainloop()
As Bryan Oakley mentions in the comments, it's better to just update the text string of the Canvas Text item, rather than trashing the old Text item and building a fresh one every second. So here's a new version derived from your code.
I use time.strftime
to build the time string because it gives nicer output than simply slicing the struct_time
object returned by time.localtime
: it always uses 2 digits for the hours, minutes, and seconds components, and you can easily add colons (or whatever) to the format string. Please see the linked docs for all the format options that strftime
provides.
I've also put the GUI into a class. That's not really necessary for such a simple GUI, but it's a good habit to get into because it makes the code more modular.
import tkinter as tk
from time import strftime
class Clock:
def __init__(self):
root = tk.Tk()
root.title("Clock")
root.resizable(False, False)
self.canvas = canvas = tk.Canvas(root, width=200, height=100,
bg="black", cursor="target")
canvas.create_rectangle((20, 20), (180, 80), outline="ghostwhite")
canvas.create_text((100, 50), tag = "text",
fill="white", font=("Verdana", 20, "bold"))
canvas.pack()
self.show_time()
root.mainloop()
def show_time(self):
w = self.canvas
w.itemconfig("text", text=strftime('%H %M %S'))
w.after(1000, self.show_time)
if "__main__" == __name__:
Clock()