Tkinter变量不随功能中的Checkbutton更改

时间:2020-08-10 15:57:14

标签: python tkinter

由于某种原因,我在Checkbutton变量中的代码在函数内部时不会更改工作,但是,在函数外部并在其自己的脚本中运行时才起作用。这是函数外部的代码

from tkinter import *

basket = ['apple','banana','orange']
win2 = Tk()
buttons = []
variables = []
for fruit in basket:
    variable = BooleanVar()
    checkbutton = Checkbutton(win2, text = fruit,variable = variable).pack()
    variables.append(variable)
    buttons.append(checkbutton)
Button(win2, text='Quit', command=win2.destroy).pack()
Button(win2, text='Peek', command=allstates).pack()
mainloop()

这是在函数内部定义的代码

from tkinter import *
def selectfruit():
    def allstates(): 
        for variable in variables:
            print(variable.get())
    basket = ['apple','banana','orange']
    win2 = Tk()
    print(stls)
    buttons = []
    variables = []
    for fruit in basket:
        variable = BooleanVar()
        checkbutton = Checkbutton(win2, text = fruit,variable = variable).pack(side = TOP)
        variables.append(variable)
        buttons.append(checkbutton)
    Button(win2, text='Quit', command=win2.destroy).pack()
    Button(win2, text='Peek', command=allstates).pack()

对于最重要的代码,当我选中一个复选框时,变量将变为True。对于最底层的,不管我做什么,他们都会保持为False。

2 个答案:

答案 0 :(得分:0)

为BooleanVar提供适当的主/父项:

variable = BooleanVar(win2)

如果我没记错的话,请不要明确设置主/父级,
自动使其成为隐式创建的全局根的子代
(例如在全局范围内编写root = Tk()并将其用作父级)。
(对于您来说,如果您以前在全局范围内创建了win2,
那么将被隐式使用-参见下面的示例。)

因此,您的代码可以在函数之外运行, 因为BooleanVar和CheckButton碰巧具有相同的Tk /根。

将代码放入函数中时,
BooleanVar和CheckButton获得不同的Tks /根。
(BooleanVar获取(可能是隐式创建的)全局根,
CheckButton会获取您在函数内部创建的新win2)

编辑/说明:
但是,是的,使用Toplevel可能是正确的选择。
只注意原始问题是什么
并且可以并且确实可以与多个Tk小部件一起使用。


省略父母的情况下自动育儿的例子
(直接从交互式解释器复制):

未指定父级/母版(此处为Label小部件),
之前 创建任何Tk小部件
==
隐式使用隐式创建的全局Tk / root
(这是第一个'Label()'之后弹出的窗口)
(注意:隐式创建的全局Tk会有所不同
从任何在其后显式创建的Tk窗口小部件中

>>> from tkinter import *
>>> l1 = Label()
>>> l2 = Label()
>>> id(l1.master) == id(l2.master)
True
>>> root = Tk()
>>> id(root) == id(l1.master)
False

未指定父/母(此处为Label小部件),
之后,明确创建了Tk小部件
==
隐式使用已经存在的Tk小部件

>>> from tkinter import *
>>> root = Tk()
>>> l = Label()
>>> id(root) == id(l.master)
True

答案 1 :(得分:0)

如果我们运行下面的代码,我们将发现第一个问题:

from tkinter import *

basket = ['apple','banana','orange']
win2 = Tk()
buttons = []
variables = []

for fruit in basket:
    variable = BooleanVar()
    checkbutton = Checkbutton(win2, text = fruit,variable = variable).pack()
    variables.append(variable)
    buttons.append(checkbutton)
def Peek():
    for b in buttons:
        print(f'this is button {b}')
Button(win2, text='top', command=win2.destroy).pack()
Button(win2, text='Peek', command=Peek).pack()

win2.mainloop()

Seperate your layout managemenet from your initialization

下一个问题是您两次致电Tk()。这可能会引起混乱,甚至导致您的程序freeze or crash