Tkinter:选择所有单选按钮

时间:2017-04-29 21:18:51

标签: python tkinter

screenshot of popup window showing most radiobuttons pre-selected

为什么在新窗口打开时单击按钮时此代码中的所有单选按钮都被选中了?

class CodeButton:
    def __init__(self, root):
        self.btn = Button(root, text="Code",width=20, height=1,bg="white", fg="black")
        self.btn.bind("<Button-1>", make_code_window)
        self.btn.pack() 


def make_code_window(event):
    new_root = Toplevel()
    new_root.minsize(width=300, height=300)
    var = IntVar()
    var.set(0)
    for i in range(8):
        Radiobutton(new_root, text=str(i), variable=var, value=i).pack()


def main():
    root = Tk()
    root.minsize(width=400, height=250)
    CodeButton(root)
    root.mainloop()

2 个答案:

答案 0 :(得分:0)

这与将IntVar存储在函数中的局部变量中有关,该函数将在make_code_window()函数返回后立即被丢弃。您可以通过IntVar窗口小部件的new_root属性来解决问题,因此它至少与使用它的小部件一样长。

您的示例中的代码在某种意义上是不太现实的,通常会想要在Python代码中的其他地方使用IntVar的当前值,但这是不可能的它只存储在局部变量中,该变量仅在执行创建它的函数期间存在。

try:
    from tkinter import *
except ImportError:  # Python 2
    from Tkinter import *

class CodeButton:
    def __init__(self, root):
        self.btn = Button(root, text="Code",width=20, height=1,bg="white", fg="black")
        self.btn.bind("<Button-1>", make_code_window)
        self.btn.pack()


def make_code_window(event):
    new_root = Toplevel()
    new_root.minsize(width=300, height=300)
    var = new_root.var = IntVar()  # changed
    var.set(0)
    for i in range(8):
        Radiobutton(new_root, text=str(i), variable=var, value=i).pack()


def main():
    root = Tk()
    root.minsize(width=400, height=250)
    CodeButton(root)
    root.mainloop()

main()

答案 1 :(得分:0)

跟进我在other answer的评论部分进行的讨论。

是的,将IntVar作为参数传递给事件处理函数 有点棘手 - 事实上它有时被称为The extra arguments trick;-)

以下是将其应用于您的代码的示例:

try:
    from tkinter import *
except ImportError:  # Python 2
    from Tkinter import *


class CodeButton:
    def __init__(self, root):
        self.btn = Button(root, text="Code",width=20, height=1,bg="white", fg="black")
        self.btn.bind("<Button-1>",
                      # Extra Arguments Trick
                      lambda event, var=root.var: make_code_window(event, var))
        self.btn.pack()


def make_code_window(event, var):  # note added "var" argument
    new_root = Toplevel()
    new_root.minsize(width=300, height=300)
    var.set(-99)  # deselect by using value not associated with any RadioButtons
    for i in range(8):
        Radiobutton(new_root, text=str(i), variable=var, value=i).pack()

def main():
    root = Tk()
    root.minsize(width=400, height=250)
    root.var = IntVar()  # create it here to give access to it in the rest of your code
    CodeButton(root)
    root.mainloop()

main()