I tired creating a countdown timer. During the duration of the timer the user should be able to enter text. However, it only displays the text after the .after() period (I think thats whats happening at least). It updates after each period and then it displays the text. Is there any workaround for this? Is there any other way to create a countdown timer that would avoid this issue?
import tkinter
from tkinter import *
def showClue(clue):
# Create window
root = tkinter.Tk()
root.state('zoomed')
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
# Frame
clue_frame = tkinter.Frame(root, bg='#0000AF')
clue_frame.pack(expand=True, fill='both')
# Clue label
clue = tkinter.Label(clue_frame, text=clue, bg='#0000AF', fg='white')
clue.config(font=('ITC Korinna Std', 60), wraplength=1250)
# Input
userinput = tkinter.Entry(clue_frame, width=50)
userinput.config(font=('ITC Korinna Std', 25))
# Countdown timer
timer = tkinter.IntVar()
timer.set(15)
time = tkinter.Label(clue_frame,textvariable=timer, bg='#0000AF', fg='white')
time.config(font=('ITC Korinna Std', 50),padx=10,pady=10)
time.pack(anchor='c',expand=True)
clue.pack(anchor= 'c',expand=True)
userinput.pack(anchor='c',expand=True)
timeleft = timer.get()
# Update countdown timer after each second
while timeleft > -1:
root.after(1000)
timer.set(timeleft)
timeleft -= 1
root.update()
root.mainloop()
showClue('test')
What I want this code to do is display the text as the user is typing it and not just after every update.
CodePudding user response:
The root.after method is used to perform some kind of callback as the second parameter for the action it should perform once the time has passed. To fix just create a callback function that updates the variable every second. and continues the countdown inside of the callback.
For example:
import tkinter
from tkinter import *
def countdown(root, timer): # this is the callback function
timeleft = timer.get()
if timeleft > 0:
timer.set(timeleft-1)
root.after(1000, countdown, root, timer) # reschedule callback
def showClue(clue):
# Create window
root = tkinter.Tk()
root.state('zoomed')
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
# Frame
clue_frame = tkinter.Frame(root, bg='#0000AF')
clue_frame.pack(expand=True, fill='both')
# Clue label
clue = tkinter.Label(clue_frame, text=clue, bg='#0000AF', fg='white')
clue.config(font=('ITC Korinna Std', 60), wraplength=1250)
# Input
userinput = tkinter.Entry(clue_frame, width=50)
userinput.config(font=('ITC Korinna Std', 25))
# Countdown timer
timer = tkinter.IntVar()
timer.set(15)
time = tkinter.Label(clue_frame,textvariable=timer, bg='#0000AF', fg='white')
time.config(font=('ITC Korinna Std', 50),padx=10,pady=10)
time.pack(anchor='c',expand=True)
clue.pack(anchor= 'c',expand=True)
userinput.pack(anchor='c',expand=True)
root.after(1000,countdown, root, timer) # start countdown
root.mainloop()
showClue('test')