为什么链接这些 Python tkinter checkbuttons?

Why are these Python tkinter checkbuttons linked?

我目前正在尝试创建一个 GUI 来比较两个不同文件夹之间的文件,并拥有一个我现在正在尝试构建的基本框架。

我在 window 的左侧、右侧和底部有三个框架,每个框架都有两个复选按钮。我希望能够 select 每个复选按钮彼此独立但是每次我点击任何一个框架的第一个复选按钮时,其他框架的第一个复选按钮也会同时 selects/deselects .

为什么会这样,如何让它们彼此独立工作?这是我的参考代码:

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()

我不确定为什么会发生这种情况,但是您可以通过将复选按钮与变量相关联来使其独立:

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()


TL;DR

您需要为每个复选按钮指定唯一的 variable

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

发生了什么

复选按钮需要一个与其关联的变量。您没有明确设置变量,因此 tkinter 正在创建默认值。 Tkinter 通过创建以检查按钮名称命名的内部变量来做到这一点。

当您创建小部件但不给它们命名时,tkinter 将选择默认名称。全名包括整个小部件层次结构的名称。因此,例如,check_L1 的内部名称是 .!frame.!checkbutton'check_R1 的名称是 .!frame2.!checkbuttonchecktype1 的内部名称是 '.!frame3.!checkbutton'.

当 tkinter 为复选按钮创建默认变量时,它仅使用变量全名的最后一个组成部分。因此,对于 check_L1,它创建了一个名为 !checkbutton 的内部变量。 check_R1 的内部变量也是 !checkbuttonchecktype2 的内部变量也是如此。

因为所有这些复选按钮共享同一个内部变量,所以它们是相互关联的。


注意:如果您在循环中创建大量复选框,则可以将对每个复选框的引用保存在一个数组中。例如:

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()}")