In this tutorial, we will build an interactive countdown timer using the ttkbootstrap library in Tkinter. The timer allows users to:
# Import required libraries
import ttkbootstrap as tb
# Function to start countdown
def start_countdown():
duration = int(meter.amountusedvar.get()) # Get value from meter
if duration == 0:
meter.configure(subtext="Set a value!", bootstyle="danger")
return
countdown(duration) # Start countdown
0
, it displays an error message.countdown()
function.after()
# Countdown function using after()
def countdown(remaining_time):
if remaining_time >= 0:
if root.winfo_exists(): # Check if window is open
meter.configure(amountused=remaining_time, subtext=f"{remaining_time} sec remaining")
root.after(1000, countdown, remaining_time - 1)
else:
meter.configure(subtext="Time Over!", bootstyle="danger") # Show "Time Over"
after(1000, function)
instead of time.sleep(1)
to avoid blocking the UI.# 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=30, amounttotal=60,
subtext="Set Time & Click Start")
meter.grid(row=0, column=0, padx=20, pady=20)
# Start Button
start_button = tb.Button(root, text="Start", bootstyle="success", command=start_countdown)
start_button.grid(row=1, column=0, pady=10)
import ttkbootstrap as tb
# Function to start countdown
def start_countdown():
duration = int(meter.amountusedvar.get()) # Get value from meter
if duration == 0:
meter.configure(subtext="Set a value!", bootstyle="danger")
return
countdown(duration) # Start countdown
# Countdown function using after()
def countdown(remaining_time):
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)
else:
return # Stop if window is closed
else:
meter.configure(subtext="Time Over!", bootstyle="danger") # Show "Time Over"
# Create main window
root = tb.Window(themename="superhero") # change the themename
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)
# Start Button
start_button = tb.Button(root, text="Start",
bootstyle="success", command=start_countdown)
start_button.grid(row=1, column=0, pady=10)
# Run the application
root.mainloop()
This extension to the existing countdown timer dynamically updates the bootstyle (color) of the meter in real-time when:
get_bootstyle(value)
- Function to Determine BootstyleThis function selects the appropriate bootstyle based on the remaining time:
def get_bootstyle(value):
if value <= 10:
return "danger" # Red (Critical)
elif value <= 20:
return "warning" # Yellow (Caution)
elif value <= 40:
return "info" # Blue (Normal)
else:
return "success" # Green (Safe)
update_meter_style(*args)
- Live Bootstyle UpdateThis function updates the meterβs bootstyle instantly when the user interacts with it.
def update_meter_style(*args):
value = int(meter.amountusedvar.get()) # Get current meter value
bootstyle = get_bootstyle(value) # Get corresponding bootstyle
meter.configure(bootstyle=bootstyle, subtext=f"{value} sec remaining")
*args
? The trace_add()
function passes 3 arguments (name
, index
, mode
), so using *args
prevents errors.
To ensure the bootstyle updates when the user moves the meter, we bind the function using:
meter.amountusedvar.trace_add("write", update_meter_style)
import ttkbootstrap as tb
# Function to determine bootstyle based on time value
def get_bootstyle(value):
if value <= 10:
return "danger"
elif value <= 20:
return "warning"
elif value <= 40:
return "info"
else:
return "success"
# Function to update meter style dynamically
def update_meter_style(*args):
value = int(meter.amountusedvar.get()) # Get current meter value
bootstyle = get_bootstyle(value)
meter.configure(bootstyle=bootstyle, subtext=f"{value} sec remaining")
# Function to start countdown
def start_countdown():
duration = int(meter.amountusedvar.get()) # Get value from meter
if duration == 0:
meter.configure(subtext="Set a value!", bootstyle="danger")
return
countdown(duration) # Start countdown
# Countdown function using after()
def countdown(remaining_time):
if remaining_time >= 0:
if root.winfo_exists(): # Check if window is still open
bootstyle = get_bootstyle(remaining_time)
meter.configure(amountused=remaining_time,
subtext=f"{remaining_time} sec remaining",
bootstyle=bootstyle)
root.after(1000, countdown, remaining_time - 1)
else:
return # Stop if window is closed
else:
meter.configure(subtext="Time Over!", bootstyle="danger") # Show "Time Over"
# Create main window
root = tb.Window(themename="superhero") # Change the themename
root.title("www.plus2net.com Interactive Countdown Timer")
# Interactive Meter Widget
meter = tb.Meter(root, bootstyle="success", 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)
# Bind the update function to mouse interaction (Fix: Use *args in function)
meter.amountusedvar.trace_add("write", update_meter_style)
# Start Button
start_button = tb.Button(root, text="Start",
bootstyle="success", command=start_countdown)
start_button.grid(row=1, column=0, pady=10)
# Run the application
root.mainloop()
This tutorial demonstrated how to create an interactive countdown timer using ttkbootstrap in Tkinter. The timer updates dynamically using after()
and remains responsive, making it a great addition to GUI-based applications.
To integrate this countdown timer into other applications, it is recommended to use threading so that the countdown runs independently without freezing the main application.
By combining threading
with the ttkbootstrap
countdown timer, we can build responsive and time-dependent GUI applications in Python!