Set breaks button creates multiple popups

Question:

I was creating an app in order to send the user a popup screen message reminding their breaks in a shift. The users have assigned break times and the following app is used to keep their breaks in check. The .after loop keeps increasing whenever I click the "Set" button.

The code works fine as long as you click the button once. But the number of popups increases when I click the button. I understand that it is to do with the after loop but I have no idea on how to stop it. What I want is to limit the number of popups to one no matter who many times the button is pressed. But the break times should be updated when the button is pressed.

PS: Check the console to get an idea of the issue. You will see the number of presses of the button increases the number of check_breakoutputs.

PS: The popups are blank at the moment.

The interface should look something like this

The interface should look something like this

The proposed popup

The proposed popup

from tkinter import *
from tkinter import ttk
from datetime import datetime

root = Tk()

root.title("Fusion Calculator")
root.geometry("700x400")
root.resizable(0, 0)

scheduler_frame = LabelFrame(root, text='Scheduler')
scheduler_frame.pack(fill=X)

scheduler_top_frame = Frame(scheduler_frame)
scheduler_top_frame.pack(fill=X)

hours_label = Label(scheduler_top_frame, text="HH")
hours_label.grid(row=0, column=1, padx=10)

minutes_label = Label(scheduler_top_frame, text="MM")
minutes_label.grid(row=0, column=2, padx=10)

seconds_label = Label(scheduler_top_frame, text="SS")
seconds_label.grid(row=0, column=3, padx=10)

first_break_label = Label(scheduler_top_frame, text="1st Break:")
first_break_label.grid(row=1, column=0, pady=5)

second_break_label = Label(scheduler_top_frame, text="2nd Break:")
second_break_label.grid(row=2, column=0, pady=5)

meal_break_label = Label(scheduler_top_frame, text="Meal Break:")
meal_break_label.grid(row=3, column=0, pady=5)

logout_label = Label(scheduler_top_frame, text="Logout:")
logout_label.grid(row=4, column=0, pady=5)

hour_time_values = ('00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
                    '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
                    '20', '21', '22', '23')

other_time_values = ('00', '01', '02', '03', '04', '05', '06', '07', '08',
                     '09', '10', '11', '12', '13', '14', '15', '16', '17',
                     '18', '19', '20', '21', '22', '23', '24', '25', '26',
                     '27', '28', '29', '30', '31', '32', '33', '34', '35',
                     '36', '37', '38', '39', '40', '41', '42', '43', '44',
                     '45', '46', '47', '48', '49', '50', '51', '52', '53',
                     '54', '55', '56', '57', '58', '59')

first_break_hour_value = StringVar()
first_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                     width=2,
                                     textvariable=first_break_hour_value)
first_break_hour_drop['values'] = hour_time_values
first_break_hour_drop.grid(row=1, column=1)
first_break_hour_drop.current(0)

first_break_minute_value = StringVar()
first_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                       width=2,
                                       textvariable=first_break_minute_value)
first_break_minute_drop['values'] = other_time_values
first_break_minute_drop.grid(row=1, column=2)
first_break_minute_drop.current(0)

first_break_second_value = StringVar()
first_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                       width=2,
                                       textvariable=first_break_second_value)
first_break_second_drop['values'] = other_time_values
first_break_second_drop.grid(row=1, column=3)
first_break_second_drop.current(0)

second_break_hour_value = StringVar()
second_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=second_break_hour_value)
second_break_hour_drop['values'] = hour_time_values
second_break_hour_drop.grid(row=2, column=1)
second_break_hour_drop.current(0)

second_break_minute_value = StringVar()
second_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                        width=2,
                                        textvariable=second_break_minute_value)
second_break_minute_drop['values'] = other_time_values
second_break_minute_drop.grid(row=2, column=2)
second_break_minute_drop.current(0)

second_break_second_value = StringVar()
second_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                        width=2,
                                        textvariable=second_break_second_value)
second_break_second_drop['values'] = other_time_values
second_break_second_drop.grid(row=2, column=3)
second_break_second_drop.current(0)

meal_break_hour_value = StringVar()
meal_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                    width=2,
                                    textvariable=meal_break_hour_value)
meal_break_hour_drop['values'] = hour_time_values
meal_break_hour_drop.grid(row=3, column=1)
meal_break_hour_drop.current(0)

meal_break_minute_value = StringVar()
meal_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=meal_break_minute_value)
meal_break_minute_drop['values'] = other_time_values
meal_break_minute_drop.grid(row=3, column=2)
meal_break_minute_drop.current(0)

meal_break_second_value = StringVar()
meal_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=meal_break_second_value)
meal_break_second_drop['values'] = other_time_values
meal_break_second_drop.grid(row=3, column=3)
meal_break_second_drop.current(0)

logout_hour_value = StringVar()
logout_hour_drop = ttk.Combobox(scheduler_top_frame,
                                width=2,
                                textvariable=logout_hour_value)
logout_hour_drop['values'] = hour_time_values
logout_hour_drop.grid(row=4, column=1)
logout_hour_drop.current(0)

logout_minute_value = StringVar()
logout_minute_drop = ttk.Combobox(scheduler_top_frame,
                                  width=2,
                                  textvariable=logout_minute_value)
logout_minute_drop['values'] = other_time_values
logout_minute_drop.grid(row=4, column=2)
logout_minute_drop.current(0)

logout_second_value = StringVar()
logout_second_drop = ttk.Combobox(scheduler_top_frame,
                                  width=2,
                                  textvariable=logout_second_value)
logout_second_drop['values'] = other_time_values
logout_second_drop.grid(row=4, column=3)
logout_second_drop.current(0)

def set_breaks():
    check_break = datetime.now(sri_lankan_time).strftime("%H:%M:%S")

    first_break_time = f'{first_break_hour_value.get()}:{first_break_minute_value.get()}:{first_break_second_value.get()}'

    second_break_time = f'{second_break_hour_value.get()}:{second_break_minute_value.get()}:{second_break_second_value.get()}'

    meal_break_time = f'{meal_break_hour_value.get()}:{meal_break_minute_value.get()}:{meal_break_second_value.get()}'

    logout_time = f'{logout_hour_value.get()}:{logout_minute_value.get()}:{logout_second_value.get()}'

    if check_break == first_break_time:
        popup_first_break = Toplevel(root)
        popup_first_break.title('Official Break')
        popup_first_break_title_bar = Label(popup_first_break, text='OFFICIAL BREAK', fg='Red')
        popup_first_break_title_bar.pack()
        print('Working')
    elif check_break == second_break_time:
        popup_second_break = Toplevel(root)
        popup_second_break.title('Official Break 2')
        popup_second_break_title_bar = Label(popup_second_break, text='OFFICIAL BREAK 2', fg='Red')
        popup_second_break_title_bar.pack()
        print('Working')
    elif check_break == meal_break_time:
        popup_meal_break = Toplevel(root)
        popup_meal_break.title('Official Break')
        popup_meal_break_title_bar = Label(popup_meal_break, text='MEAL BREAK', fg='Red')
        popup_meal_break_title_bar.pack()
        print('Working')
    elif check_break == logout_time:
        popup_logout = Toplevel(root)
        popup_logout.title('Official Break')
        popup_logout_title_bar = Label(popup_logout, text='LOGOUT', fg='Red')
        popup_logout_title_bar.pack()
        print('Working')
    else:
        print(check_break)

    set_breaks_button.after(1000, set_breaks)

set_breaks_button = Button(scheduler_top_frame,
                           text='Set',
                           command=set_breaks)
set_breaks_button.grid(row=5, column=3)

root.mainloop()
Asked By: Muneeb Asmone

||

Answers:

What you could do is create a global variable loop_active initially set to False, and then on the first button click at the end of the set_breaks function have it fire a seperate function that controls the 1 second loop, but only if the loop_active is set to false, otherwise it will just perform the regular checks.

It is kind of a combination of what was suggested in the comments to some degree. See inline notes for more details.

for example:

from tkinter import *
from tkinter import ttk
from datetime import datetime

root = Tk()

root.title("Fusion Calculator")
root.geometry("700x400")
root.resizable(0, 0)

scheduler_frame = LabelFrame(root, text='Scheduler')
scheduler_frame.pack(fill=X)

scheduler_top_frame = Frame(scheduler_frame)
scheduler_top_frame.pack(fill=X)

hours_label = Label(scheduler_top_frame, text="HH")
hours_label.grid(row=0, column=1, padx=10)

minutes_label = Label(scheduler_top_frame, text="MM")
minutes_label.grid(row=0, column=2, padx=10)

seconds_label = Label(scheduler_top_frame, text="SS")
seconds_label.grid(row=0, column=3, padx=10)

first_break_label = Label(scheduler_top_frame, text="1st Break:")
first_break_label.grid(row=1, column=0, pady=5)

second_break_label = Label(scheduler_top_frame, text="2nd Break:")
second_break_label.grid(row=2, column=0, pady=5)

meal_break_label = Label(scheduler_top_frame, text="Meal Break:")
meal_break_label.grid(row=3, column=0, pady=5)

logout_label = Label(scheduler_top_frame, text="Logout:")
logout_label.grid(row=4, column=0, pady=5)

hour_time_values = ('00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
                    '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
                    '20', '21', '22', '23')

other_time_values = ('00', '01', '02', '03', '04', '05', '06', '07', '08',
                     '09', '10', '11', '12', '13', '14', '15', '16', '17',
                     '18', '19', '20', '21', '22', '23', '24', '25', '26',
                     '27', '28', '29', '30', '31', '32', '33', '34', '35',
                     '36', '37', '38', '39', '40', '41', '42', '43', '44',
                     '45', '46', '47', '48', '49', '50', '51', '52', '53',
                     '54', '55', '56', '57', '58', '59')

first_break_hour_value = StringVar()
first_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                     width=2,
                                     textvariable=first_break_hour_value)
first_break_hour_drop['values'] = hour_time_values
first_break_hour_drop.grid(row=1, column=1)
first_break_hour_drop.current(0)

first_break_minute_value = StringVar()
first_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                       width=2,
                                       textvariable=first_break_minute_value)
first_break_minute_drop['values'] = other_time_values
first_break_minute_drop.grid(row=1, column=2)
first_break_minute_drop.current(0)

first_break_second_value = StringVar()
first_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                       width=2,
                                       textvariable=first_break_second_value)
first_break_second_drop['values'] = other_time_values
first_break_second_drop.grid(row=1, column=3)
first_break_second_drop.current(0)

second_break_hour_value = StringVar()
second_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=second_break_hour_value)
second_break_hour_drop['values'] = hour_time_values
second_break_hour_drop.grid(row=2, column=1)
second_break_hour_drop.current(0)

second_break_minute_value = StringVar()
second_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                        width=2,
                                        textvariable=second_break_minute_value)
second_break_minute_drop['values'] = other_time_values
second_break_minute_drop.grid(row=2, column=2)
second_break_minute_drop.current(0)

second_break_second_value = StringVar()
second_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                        width=2,
                                        textvariable=second_break_second_value)
second_break_second_drop['values'] = other_time_values
second_break_second_drop.grid(row=2, column=3)
second_break_second_drop.current(0)

meal_break_hour_value = StringVar()
meal_break_hour_drop = ttk.Combobox(scheduler_top_frame,
                                    width=2,
                                    textvariable=meal_break_hour_value)
meal_break_hour_drop['values'] = hour_time_values
meal_break_hour_drop.grid(row=3, column=1)
meal_break_hour_drop.current(0)

meal_break_minute_value = StringVar()
meal_break_minute_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=meal_break_minute_value)
meal_break_minute_drop['values'] = other_time_values
meal_break_minute_drop.grid(row=3, column=2)
meal_break_minute_drop.current(0)

meal_break_second_value = StringVar()
meal_break_second_drop = ttk.Combobox(scheduler_top_frame,
                                      width=2,
                                      textvariable=meal_break_second_value)
meal_break_second_drop['values'] = other_time_values
meal_break_second_drop.grid(row=3, column=3)
meal_break_second_drop.current(0)

logout_hour_value = StringVar()
logout_hour_drop = ttk.Combobox(scheduler_top_frame,
                                width=2,
                                textvariable=logout_hour_value)
logout_hour_drop['values'] = hour_time_values
logout_hour_drop.grid(row=4, column=1)
logout_hour_drop.current(0)

logout_minute_value = StringVar()
logout_minute_drop = ttk.Combobox(scheduler_top_frame,
                                  width=2,
                                  textvariable=logout_minute_value)
logout_minute_drop['values'] = other_time_values
logout_minute_drop.grid(row=4, column=2)
logout_minute_drop.current(0)

logout_second_value = StringVar()
logout_second_drop = ttk.Combobox(scheduler_top_frame,
                                  width=2,
                                  textvariable=logout_second_value)
logout_second_drop['values'] = other_time_values
logout_second_drop.grid(row=4, column=3)
logout_second_drop.current(0)

loop_active = False  # global variable set to false

def check_breaks():   # new loop function that runs set_breaks and reschedules
    set_breaks()      # for 1 second later.
    root.after(1000, check_breaks)

def set_breaks():
    check_break = datetime.now().strftime("%H:%M:%S")

    first_break_time = f'{first_break_hour_value.get()}:{first_break_minute_value.get()}:{first_break_second_value.get()}'

    second_break_time = f'{second_break_hour_value.get()}:{second_break_minute_value.get()}:{second_break_second_value.get()}'

    meal_break_time = f'{meal_break_hour_value.get()}:{meal_break_minute_value.get()}:{meal_break_second_value.get()}'

    logout_time = f'{logout_hour_value.get()}:{logout_minute_value.get()}:{logout_second_value.get()}'

    if check_break == first_break_time:
        popup_first_break = Toplevel(root)
        popup_first_break.title('Official Break')
        popup_first_break_title_bar = Label(popup_first_break, text='OFFICIAL BREAK', fg='Red')
        popup_first_break_title_bar.pack()
        print('Working')
    elif check_break == second_break_time:
        popup_second_break = Toplevel(root)
        popup_second_break.title('Official Break 2')
        popup_second_break_title_bar = Label(popup_second_break, text='OFFICIAL BREAK 2', fg='Red')
        popup_second_break_title_bar.pack()
        print('Working')
    elif check_break == meal_break_time:
        popup_meal_break = Toplevel(root)
        popup_meal_break.title('Official Break')
        popup_meal_break_title_bar = Label(popup_meal_break, text='MEAL BREAK', fg='Red')
        popup_meal_break_title_bar.pack()
        print('Working')
    elif check_break == logout_time:
        popup_logout = Toplevel(root)
        popup_logout.title('Official Break')
        popup_logout_title_bar = Label(popup_logout, text='LOGOUT', fg='Red')
        popup_logout_title_bar.pack()
        print('Working')
    else:
        print(check_break)
    global loop_active
    if not loop_active:   #  This will only run when loop_active is false
        loop_active = True   # Set loop_active to True so it doesn't run again
        check_breaks()       

set_breaks_button = Button(scheduler_top_frame,
                           text='Set',
                           command=set_breaks)
set_breaks_button.grid(row=5, column=3)

root.mainloop()
Answered By: Alexander
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.