Why are these Python tkinter checkbuttons linked?

坚强是说给别人听的谎言 提交于 2020-06-07 05:53:28

问题


I'm currently trying to create a GUI to compare files between two different folders and have a rudimentary framework that I'm trying to build off of right now.

I have three frames on the left, right, and bottom of the window with two checkbuttons each. I want to be able to select each checkbutton independently of each other but every time I click on the first checkbutton of any one of the frames, the first checkbutton for the other frames also selects/deselects at the same time.

Why is this the case, and how do I make them work independently from each other? Here's my code for reference:

from tkinter import *

root = Tk()

leftFrame = Frame(root, bg = "#4d94ff")
leftFrame.pack(side = LEFT, fill = BOTH)

rightFrame = Frame(root, bg = "#ff4d4d")
rightFrame.pack(side = RIGHT, fill = BOTH)

bottomFrame = Frame(root, bg = "#5cd65c")
bottomFrame.pack(side = BOTTOM)

check_L1 = Checkbutton(leftFrame, text = "C1", bg = "#4d94ff")
check_L2 = Checkbutton(leftFrame, text = "C2", bg = "#4d94ff")

check_R1 = Checkbutton(rightFrame, text = "C1", bg = "#ff4d4d")
check_R2 = Checkbutton(rightFrame, text = "C2", bg = "#ff4d4d")

checktype1 = Checkbutton(bottomFrame, text = "Check Type 1", bg = "#5cd65c")
checktype2 = Checkbutton(bottomFrame, text = "Check Type 2", bg = "#5cd65c")

check_L1.grid(row = 0)
check_L2.grid(row = 0, column = 1)
check_R1.grid(row = 0)
check_R2.grid(row = 0, column = 1)
checktype1.grid(row = 0)
checktype2.grid(row = 1)


root.mainloop()

回答1:


TL;DR

You need to specify a unique variable with each checkbutton.

var_L1 = tk.IntVar()
var_R1 = tk.IntVar()
...
check_L1 = Checkbutton(..., variable=var_L1)
check_R1 = Checkbutton(..., variable=var_R1)
...

What is happening

Checkbuttons require a variable to be associated with them. You are't explicitly setting a variable so tkinter is creating defaults. Tkinter does this by creating internal variables named after the checkbutton name.

When you create widgets and don't give them names, tkinter will pick default names. The full name includes the names of entire widget hierarchy. So, for example, the internal name for check_L1 is .!frame.!checkbutton', the name for check_R1 is .!frame2.!checkbutton, and the internal name for checktype1 is '.!frame3.!checkbutton'.

When tkinter creates the default variables for the checkbuttons it uses only the last component of the full name for the variables. Thus, for check_L1 it creates an internal variable named !checkbutton. The internal variable for check_R1 is also !checkbutton, as is the internal variable for checktype2.

Because all of these checkbuttons share the same internal variable, they are linked.


Note: if you are creating a lot of checkboxes in a loop, you can save the reference to each checkbutton in an array. For example:

vars = []
for i in range(x):
    vars.append[tk.IntVar())
...
check_L1 = Checkbutton(..., variable=vars[0])
...
print(f"the value of L1 is {vars[0].get()}")



回答2:


I'm not sure why this happens, but you can make checkbuttons independent by associating them with a variable:

from tkinter import *

root = Tk()

leftFrame = Frame(root, bg = "#4d94ff")
leftFrame.pack(side = LEFT, fill = BOTH)

rightFrame = Frame(root, bg = "#ff4d4d")
rightFrame.pack(side = RIGHT, fill = BOTH)

bottomFrame = Frame(root, bg = "#5cd65c")
bottomFrame.pack(side = BOTTOM)

check_L1 = Checkbutton(leftFrame, text = "C1", bg = "#4d94ff", variable=IntVar())
check_L2 = Checkbutton(leftFrame, text = "C2", bg = "#4d94ff", variable=IntVar())

check_R1 = Checkbutton(rightFrame, text = "C1", bg = "#ff4d4d", variable=IntVar())
check_R2 = Checkbutton(rightFrame, text = "C2", bg = "#ff4d4d", variable=IntVar())

checktype1 = Checkbutton(bottomFrame, text = "Check Type 1", bg = "#5cd65c", variable=IntVar())
checktype2 = Checkbutton(bottomFrame, text = "Check Type 2", bg = "#5cd65c", variable=IntVar())

check_L1.grid(row = 0)
check_L2.grid(row = 0, column = 1)
check_R1.grid(row = 0)
check_R2.grid(row = 0, column = 1)
checktype1.grid(row = 0)
checktype2.grid(row = 1)


root.mainloop()




来源:https://stackoverflow.com/questions/58864662/why-are-these-python-tkinter-checkbuttons-linked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!