Home > Software design >  How to retain state of selection in checkbox Tkinter, also how to add value and remove same value up
How to retain state of selection in checkbox Tkinter, also how to add value and remove same value up

Time:06-19

I'm writing a code which is having multiple dynamic checkboxes, my requirement is

  1. To retain the selection of checkbox, in my current code, if I select another checkbox, first selection deselected automatically. in short I'm unable to maintain multiple checkbox checked This is the output of my code This is something I want to do

  2. To get the value and add in a list when used selected checkboxes and remove same value when user deselected checkboxes. Currently what is happening is when I select the checkbox it added the correct value in list but when I deselect same checkbox, instead of remove that value, 0 is getting appended in list. On selection added IP in list correctly On deselection 0 added in list instead of removing same IP

Below is the snippet of code I'm trying. Here eqpt_dict is a dictionary, so when user select the checkbox I want to add value of that key in a list and when user deselected the checkbox then want to remove same value from the list.

eqpt_dict = {'MDDDSERFEP1A': '10.5.30.110', 'MDDDSERFEP1B': 'x.x.x.x', 'MDDDSERFEP2A': 'x.x.x.x', 'MDDDSERFEP2B': 'x.x.x.x', 'TE02MSERFEPA': 'x.x.x.x', 'TE02MSERFEPB': 'x.x.x.x', 'TE03MSERFEPA': 'x.x.x.x', 'TE03MSERFEPB': 'x.x.x.x', 'TE05MSERFEPA': 'x.x.x.x', 'TE05MSERFEPB': 'x.x.x.x', 'TE06MSERFEPA': 'x.x.x.x', 'TE06MSERFEPB': 'x.x.x.x', 'TE09MSERFEPA': 'x.x.x.x', 'TE09MSERFEPB': 'x.x.x.x', 'TE10MSERFEPA': 'x.x.x.x', 'TE10MSERFEPB': 'x.x.x.x', 'TE14MSERFEPA': 'x.x.x.x', 'TE14MSERFEPB': 'x.x.x.x', 'TE17MSERFEPA': 'x.x.x.x', 'TE17MSERFEPB': 'x.x.x.x', 'TE19MSERFEPA': 'x.x.x.x', 'TE19MSERFEPB': 'x.x.x.x', 'TE22MSERFEPA': 'x.x.x.x', 'TE22MSERFEPB': 'x.x.x.x', 'selfServer': 'x.x.x.x'}
ip_list = list()
def checkbox_command():
    if var.get():
        if var.get() not in ip_list:
            ip_list.append(var.get())
    if not var.get():
        ip_list.remove(var.get())
    print(ip_list)

var = StringVar()
var.set('0')
for eqpt,ip in eqpt_dict.items():
    checkbutton4 = Checkbutton(text4, text=eqpt, variable=var, onvalue=ip,offvalue=0,bg='white', cursor="hand2",command=checkbox_command)
    checkbutton4.pack()

CodePudding user response:

Each checkbutton needs its own separate variable. When you do variable=var, you're assigning the same variable to every checkbutton, which means all checkbuttons will have the same value.

CodePudding user response:

In addition to Bryan Oakley's answer there is a problem with the logic in checkbox_command. var.get() returns the string '0' not the integer 0. This is Truthy and explains why unticking a box adds a '0' to the ip_list.

Below is code with a vars dictionary that holds the ticked/unticked state of the buttons. The checkbox_command then reads the state of all the button to create the latest version of ip_list

This is one of many possible approaches to the problem.

import tkinter as tk  # import as tk is safer and more flexible

root = tk.Tk()

eqpt_dict = {'MDDDSERFEP1A': '10.5.30.110', 'MDDDSERFEP1B': 'x.x.x.x', 
             'MDDDSERFEP2A': 'x.x.x.x',     'MDDDSERFEP2B': 'x.x.x.x', 
             'TE02MSERFEPA': 'x.x.x.x',     'TE02MSERFEPB': 'x.x.x.x', 
             'TE03MSERFEPA': 'x.x.x.x',     'TE03MSERFEPB': 'x.x.x.x', 
            }

ip_list = list()  # result list

def checkbox_command():
    """ Iterate through the vars dictionary and get the addresses from the 
        dictionary when the checkbox is set.
    """
    global ip_list

    # ip_list = [ eqpt_dict[ key] for key in eqpt_dict.keys() if vars[key].get() == 1 ]
    # List comprehension if you prefer.

    ip_list = []
    for key in eqpt_dict.keys():
        if vars[ key ].get() == 1:
            ip_list.append( eqpt_dict[ key ] )
    print( ip_list ) 

vars = {}   # A dict of vars.  Each checkbox needs it's own StringVar
            # The dictionary keeps the state of each Checkbox

for eqpt in eqpt_dict.keys():
    vars[ eqpt ] = tk.IntVar( value = 0 )
    checkbutton4 = tk.Checkbutton( root, text = eqpt, variable = vars[ eqpt ], 
        onvalue = 1, offvalue = 0, bg = 'white', cursor = "hand2",
        command = checkbox_command )
    checkbutton4.pack()

root.mainloop()
  • Related