In this tutorial, we will create an interactive countdown timer using Tkinter and TtkBootstrap. On click of the start button the timer will enable a text box for typing while the timer is running, and disable it once the timer ends. At the end, it will calculate and display the number of characters typed and the typing speed (characters per second).
This project is useful for typing tests, speed challenges, or any timed data entry applications.
# Import required modules
import ttkbootstrap as tb
import tkinter as tk
def start_countdown():
# Get time from the interactive meter
duration = int(meter.amountusedvar.get())
if duration == 0:
meter.configure(subtext="Set a value!", bootstyle="danger")
return
text_widget.config(state="normal") # Enable text entry
text_widget.delete("1.0", tk.END) # Clear previous text
countdown(duration, duration) # Start countdown
def countdown(remaining_time, total_time):
if remaining_time >= 0:
meter.configure(
amountused=remaining_time,
subtext=f"{remaining_time} sec remaining"
)
root.after(1000, countdown, remaining_time - 1, total_time)
else:
text_widget.config(state="disabled") # Disable text entry
typed_text = text_widget.get("1.0", tk.END).strip()
char_count = len(typed_text)
typing_speed = char_count / total_time if total_time > 0 else 0
meter.configure(
subtext=f"Time Over! {char_count} chars, {typing_speed:.2f} cps",
bootstyle="danger"
)
root.after(1000, countdown, remaining_time - 1, total_time)
to update the timer every second.# Create main window
root = tb.Window(themename="superhero")
root.title("Interactive Countdown Timer")
# Interactive Meter Widget
meter = tb.Meter(root, bootstyle="warning", interactive=True,
stripethickness=6, meterthickness=20,
amountused=33, amounttotal=60,
subtext="Set Time & Click Start")
meter.grid(row=0, column=0, padx=20, pady=20)
# Text Widget (Initially Disabled)
text_widget = tk.Text(root, height=5, width=40, state="disabled")
text_widget.grid(row=1, column=0, padx=20, pady=10)
# Start Button
start_button = tb.Button(root, text="Start", bootstyle="success", command=start_countdown)
start_button.grid(row=2, column=0, pady=10)
root.mainloop()
import ttkbootstrap as tb
import tkinter as tk
# Function to start countdown
def start_countdown():
""" Starts the countdown timer and enables the text box. """
duration = int(meter.amountusedvar.get()) # Get value from meter
if duration == 0:
meter.configure(subtext="Set a value!", bootstyle="danger")
return
text_widget.config(state="normal") # Enable text entry
text_widget.delete("1.0", tk.END) # Clear previous text
#text_widget.focus() # Keeping cursor inside Text widget at start
countdown(duration, duration) # Start countdown
# Countdown function using after()
def countdown(remaining_time, total_time):
""" Updates the meter every second and disables the text box when time is up. """
if remaining_time >= 0:
if root.winfo_exists(): # Check if window is still open
meter.configure(
amountused=remaining_time,
subtext=f"{remaining_time} sec remaining"
)
root.after(1000, countdown, remaining_time - 1, total_time)
else:
return # Stop if window is closed
else:
# Disable text entry when time is over
text_widget.config(state="disabled")
# Get the text entered by the user
typed_text = text_widget.get("1.0", tk.END).strip()
# Count the number of characters typed
char_count = len(typed_text)
# Calculate typing speed (characters per second)
typing_speed = char_count / total_time if total_time > 0 else 0
# Update the meter with typing speed info
meter.configure(
subtext=f"Time Over! {char_count} chars, {typing_speed:.2f} cps",
bootstyle="danger"
)
# Create main window
root = tb.Window(themename="superhero") # Change the theme if needed
root.title("www.plus2net.com Interactive Countdown Timer")
# Interactive Meter Widget
meter = tb.Meter(
root, bootstyle="warning", interactive=True,
stripethickness=6, meterthickness=20,
amountused=33, amounttotal=60,
subtext="Set Time & Click Start"
)
meter.grid(row=0, column=0, padx=20, pady=20)
# Text Widget (Initially Disabled)
text_widget = tk.Text(root, height=5, width=40, state="disabled")
text_widget.grid(row=1, column=0, padx=20, pady=10)
# Start Button
start_button = tb.Button(
root, text="Start", bootstyle="success",
command=start_countdown
)
start_button.grid(row=2, column=0, pady=10)
# Run the application
root.mainloop()