Home > Mobile >  Tkinter entry widget doesn't show input during root.after()
Tkinter entry widget doesn't show input during root.after()

Time:11-13

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')
  • Related