Reputation: 11
I'm not great at tkinter or even python so I've run into what should be a simple problem.
I have something like this in the middle of my project:
visible = numLevels * [IntVar(value=1)]
top = Toplevel()
settingslabel = Label(top, text='Settings', height=0, width=100)
for i in range(0, numLevels ):
check = ttk.Checkbutton(settingslabel, text='Level ' + str(i), variable=visible[i])
check.grid(column = 0, row = i)
check.var = visible[i]
settingslabel.grid(column = 0, row=0)
I want to have settings screen with a checkbox for every level, while maintaining an array of integers that represent the status of each button.
However, all checkboxes are synchronized. Meaning, when I check a box, all other boxes also become checked. I believe that this is because of the 'variable' field of the checkbutton. As the loop continues, i is updated, and as a result, visible[i] changes as well. I want to preserve the variable when I created the checkbutton. I don't understand how tkinter/python work well enough to know.
The number is levels can be any integer > 0 and is determined at runtime so I can't just unroll the loop.
Is there a better way to do this? Thanks in advance.
Upvotes: 0
Views: 452
Reputation: 3858
This is a duplicate of this SO post, but explanation below.
Its because all your boxes are sharing the same tkinter.Intvar()
object:
numlevels = 5
visible = numlevels * [IntVar(value = 1)]
for i in range(len(visible)):
print (hex(id(visible[i]))
# Outputs:
'0x67f8190'
'0x67f8190'
'0x67f8190'
'0x67f8190'
'0x67f8190'
To solve: visible = [IntVar(value = 1) for i in range(numlevels)]
Upvotes: 1