Search code examples
pythondictionarytkintercheckboxtkinter-button

Tkinter Checkedbox in python is returning False for all Machines eventhough boxes are checked


I created a tkinter checkedbox to receive input from user to see which machines from date_and_time_dictionary they want to delete. You then press a tkinter button "Print Checkbox States" and if a box was checked the program will print out the machine and the word "True" next to it and "False" otherwise. Even though some or all boxes are checked, I still get back all False for every machine.

date_and_time_dictionary = {'S120': {'Setup Start Time': 'March 28, 2023 1:55 PM', 'Loaded in Program': 'March 28, 2023 1:56 PM', 'Setup End Time': 'April 5, 2023 1:24 PM', 'Pending F/A (At-risk) Start': 'April 5, 2023 1:24 PM', 'Pending F/A (At-risk) End': 'April 7, 2023 11:51 AM'}, 'S109': {'Setup Start Time': 'April 3, 2023 9:56 AM', 'Setup End Time': 'April 4, 2023 4:59 AM'}, 'S112': {'Setup Start Time': 'April 5, 2023 7:03 AM', 'Loaded in Program': 'April 5, 2023 9:31 AM', 'Setup End Time': 'April 11, 2023 8:49 AM', 'Pending F/A (At-risk) Start': 'April 11, 2023 8:49 AM'}, 'S117': {'Setup Start Time': 'April 5, 2023 1:24 PM', 'Loaded in Program': 'April 5, 2023 1:28 PM', 'No QIP Available': 'April 6, 2023 10:20 AM', 'Setup End Time': 'April 6, 2023 3:25 PM', 'Pending F/A (At-risk) Start': 'April 6, 2023 3:25 PM', 'Pending F/A (At-risk) End': 'April 10, 2023 8:11 AM'}, 'S113': {'Setup Start Time': 'April 5, 2023 12:53 PM', 'Loaded in Program': 'April 6, 2023 6:42 AM', 'No QIP Available': 'April 5, 2023 1:02 PM', 'Setup End Time': 'April 11, 2023 5:57 AM'}, 'S101': {'Setup Start Time': 'April 4, 2023 9:25 AM', 'Setup End Time': 'April 6, 2023 6:11 AM'}, 'S119': {'Setup Start Time': 'April 7, 2023 9:13 AM', 'Loaded in Program': 'April 7, 2023 10:02 AM', 'Waiting For F/A Approval': 'April 11, 2023 8:48 AM', 'Setup End Time': 'April 10, 2023 3:32 PM', 'Pending F/A (At-risk) Start': 'April 10, 2023 3:32 PM'}, 'S111': {'Setup Start Time': 'April 3, 2023 9:30 AM', 'Waiting For F/A Approval': 'April 10, 2023 6:25 AM', 'Setup End Time': 'April 10, 2023 6:32 AM'}, 'S106': {'Setup Start Time': 'April 7, 2023 9:06 AM', 'Setup End Time': 'April 11, 2023 6:14 AM', 'Pending F/A (At-risk) Start': 'April 11, 2023 6:14 AM'}}


def delete_old_after_action_report_times():    
    # Create a Tkinter window
    root = tkinter.Tk()
    root.geometry("400x300")
    # Create a Text widget
    text_box = tkinter.Text(root)

    # Add some text to the widget
    Label(root, text ='Select which machine(s) you would like to delete?:').place(x = 65, y = 0)

    y_val = 20

    # Create a dictionary to store the state of each checkbox
    checkbox_states = {}

    # Iterate through the dictionary and create a Checkbutton for each key
    for key in date_and_time_dictionary.keys():
        var = tkinter.BooleanVar()  # Create a BooleanVar to store the checkbox state
        chk = tkinter.Checkbutton(root, text=key, variable=var)
        # chk.pack()  # Pack the Checkbutton into the window
        chk.place(x=175, y=y_val)
        y_val += 20

        # Add the checkbox state to the dictionary
        checkbox_states[key] = var

        # Add a button to print the state of each checkbox
    def print_checkbox_states():
        for key, var in checkbox_states.items():
            print(f"{key}: {var.get()}")


    button = tkinter.Button(root, text="Print Checkbox States", command=print_checkbox_states)
    button.place(x=150, y=y_val+20)
    

    root.mainloop()

What I tried and got back was: S120: False S109: False S112: False S117: False S113: False S101: False S119: False S111: False S106: False

What I expected to get back if S120, S109, and S111 were selected was: S120: True S109: True S112: False S117: False S113: False S101: False S119: False S111: True S106: False


Solution

  • The way I create my buttons is by looping through each key in my date_and_time_dictionary. My program only references the last one I created, which it saves as self.key. When I call print_checkbox_states(), it only checks this button's value. One way around this is to save all the references to these Buttons in a dictionary:

    date_and_time_dictionary = {'S120': {'Setup Start Time': 'March 28, 2023 1:55 PM', 'Loaded in Program': 'March 28, 2023 1:56 PM', 'Setup End Time': 'April 5, 2023 1:24 PM', 'Pending F/A (At-risk) Start': 'April 5, 2023 1:24 PM', 'Pending F/A (At-risk) End': 'April 7, 2023 11:51 AM'}, 'S109': {'Setup Start Time': 'April 3, 2023 9:56 AM', 'Setup End Time': 'April 4, 2023 4:59 AM'}, 'S112': {'Setup Start Time': 'April 5, 2023 7:03 AM', 'Loaded in Program': 'April 5, 2023 9:31 AM', 'Setup End Time': 'April 11, 2023 8:49 AM', 'Pending F/A (At-risk) Start': 'April 11, 2023 8:49 AM'}, 'S117': {'Setup Start Time': 'April 5, 2023 1:24 PM', 'Loaded in Program': 'April 5, 2023 1:28 PM', 'No QIP Available': 'April 6, 2023 10:20 AM', 'Setup End Time': 'April 6, 2023 3:25 PM', 'Pending F/A (At-risk) Start': 'April 6, 2023 3:25 PM', 'Pending F/A (At-risk) End': 'April 10, 2023 8:11 AM'}, 'S113': {'Setup Start Time': 'April 5, 2023 12:53 PM', 'Loaded in Program': 'April 6, 2023 6:42 AM', 'No QIP Available': 'April 5, 2023 1:02 PM', 'Setup End Time': 'April 11, 2023 5:57 AM'}, 'S101': {'Setup Start Time': 'April 4, 2023 9:25 AM', 'Setup End Time': 'April 6, 2023 6:11 AM'}, 'S119': {'Setup Start Time': 'April 7, 2023 9:13 AM', 'Loaded in Program': 'April 7, 2023 10:02 AM', 'Waiting For F/A Approval': 'April 11, 2023 8:48 AM', 'Setup End Time': 'April 10, 2023 3:32 PM', 'Pending F/A (At-risk) Start': 'April 10, 2023 3:32 PM'}, 'S111': {'Setup Start Time': 'April 3, 2023 9:30 AM', 'Waiting For F/A Approval': 'April 10, 2023 6:25 AM', 'Setup End Time': 'April 10, 2023 6:32 AM'}, 'S106': {'Setup Start Time': 'April 7, 2023 9:06 AM', 'Setup End Time': 'April 11, 2023 6:14 AM', 'Pending F/A (At-risk) Start': 'April 11, 2023 6:14 AM'}}
    
    checkbox_states = {}
    checkbox_list = []
    
    # Add a button to print the state of each checkbox
    def print_checkbox_states():
        for key in checkbox_states:
            if checkbox_states[key].get():
                checkbox_list.append(key)
        return 
    
    def delete_old_after_action_report_times():
        root = Tk()
        root.geometry("400x300")
        # # Create a Text widget
        # text_box = tkinter.Text(root)
    
        # Add some text to the widget
        Label(root, text ='Select which machine(s) you would like to delete?').place(x = 70, y = 0)
    
        y_val = 20
        
        for key in date_and_time_dictionary:
            is_selected = BooleanVar()
            checkbutton = Checkbutton(text=key, variable=is_selected)
            checkbutton.place(x=175, y=y_val)
            y_val += 20
            checkbox_states[key] = is_selected
    
    
        #checkbutton.pack()
    
        testbutton = Button(text='check test', command=print_checkbox_states)
        testbutton.place(x=165, y=y_val+20)
        
        root.mainloop() 
    

    I took print_checkbox_states() out of delete_old_after_action_report_times(). I also moved checkbox_states outside of the function and made it a global variable dictionary. Then I made a global variable list checkbox_list. I fill in the checkbox_states dictionary in delete_old_after_action_report_times(), so that I can track whether a button has been selected or not. It's easy to reference this table, because the keys are the items themselves. I then put the keys in a list to access later to know which machines I want to delete.