user3573140
user3573140

Reputation:

Tkinter GUI stopwatch/timer

How can I make the timer to update in the Canvas?

In create.text(position, **options) the default position can be overridden with anchor=tk.CENTER supposedly, but I get a:

NameError: name 'tk' is not defined

if I try to add the anchor option.

import time
from Tkinter import *

run = True; s=0; m=0; h=0

def Run():
    global run, s, m, h
    while run == True:
        time.sleep(1)
        s+=1
        if s == 59:
            m+=1; s=-1
        elif m == 59:
            h+=1; m=-1

master = Tk()
w = Canvas(master, width=1500, height=800)
w.pack()

x.create_text(
    [750, 400], anchor=tk.CENTER, text="%s:%s:%s" % (s, m, h), font=("Consolas", 400)
    )

mainloop()

Run()

If I put Run() before mainloop() the Canvas doesn't start. After mainloop() and Run() doesn't start.

mainloop(Run()) and Run() starts before Canvas.

Upvotes: 0

Views: 4873

Answers (1)

user2555451
user2555451

Reputation:

This line:

from Tkinter import *

brings all of the names from the Tkinter library into the global namspace. So, you can just access them directly:

x.create_text(
    ..., anchor=CENTER, ...
    )

You would only do tk.CENTER had you imported Tkinter like:

import Tkinter as tk

which I must say is a better approach. It is a bad practice to clutter the global namespace by doing from ... import *. Remember that:

"Namespaces are one honking great idea -- let's do more of those!"


Regarding the second part of your question, you cannot use while True: or time.sleep in the same thread as the Tkinter event loop is operating in. Doing either of these will block the Tkinter loop and cause your program to freeze.

Instead, you can use Tk.after to execute Run in the background:

from Tkinter import *

run = True
s = 0
m = 0
h = 0


def Run():
    global run, s, m, h

    # Delete old text
    w.delete('all')
    # Add new text
    w.create_text(
        [750, 400], anchor=CENTER, text="%s:%s:%s" % (s, m, h), font=("Consolas", 400)
        )

    s += 1
    if s == 59:
        m += 1
        s -= 1
    elif m == 59:
        h += 1
        m -= 1

    # After 1 second, call Run again (start an infinite recursive loop)
    master.after(1000, Run)


master = Tk()
w = Canvas(master, width=1500, height=800)
w.pack()

master.after(1, Run)  # after 1 millisecond, start Run
mainloop()

Also, I moved the call to Canvas.create_text inside the Run function so that it is updated with each call of Run. Notice too that you need to call Canvas.delete before you add the new text so that any old text is removed.

Upvotes: 2

Related Questions