且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Tkinter 单选按钮初始化错误

更新时间:2023-11-10 21:01:52

您存储变量对象(StringVar,v,在您的情况下)的位置必须保持不变,以便这种奇怪的行为不会出现.我的猜测是我们看到这种行为是因为 v 超出了范围,出现了问题.除了使用全局,我想不出有什么方法可以从函数中做到这一点.

The place where you store the variable object (StringVar, v, in your case) must persist so that this odd behavior wont show up. My guess is we're seeing this behavior because v, goes out of scope, something is going wrong. Aside from using a global, I can't think of a way to do this from a function.

损坏的代码:

from Tkinter import *

def App(master):
    v = StringVar()
    v.set('python')

    lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
    lable1.pack()

    runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
    runtimeFrame.pack(fill=X, pady=5, padx=5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=v, value=mode, indicatoron=1)
        b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    App(master)
    mainloop()

示例修复:

from Tkinter import *

def App(master, radio_var):
    radio_var.set('python')

    lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
    lable1.pack()

    runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
    runtimeFrame.pack(fill=X, pady=5, padx=5)
    for mode in ['java', 'python', 'jython']:
        b = Radiobutton(runtimeFrame, text=mode, variable=radio_var, value=mode, indicatoron=1)
        b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    radio_var = StringVar()
    App(master, radio_var)
    mainloop()

考虑到如果您有多个需要持久化的变量,您可以传入一个变量列表或字典.

Consider that if you have more than one variable that needs to persist you can pass in a list or dictionary of variables.

此外,以防万一必须在一个函数中"是家庭作业的要求,请考虑将代码包装在一个类中.我不是传统知识专家,但这似乎是组织代码的首选方式.

Also, just in case "has to be in a function" is a homework assignment requirement, consider wrapping the code in a class. I'm not a tk expert, but that would seem the preferred manner of organizing your code.

示例修复 2:

    from Tkinter import *

class App(object):
    def __init__(self, master):
        self.radio_var = StringVar()
        self.radio_var.set('python')

        lable1 = Label(master, text=' hovering over below radio buttons will cause them to look like they are selected')
        lable1.pack()

        runtimeFrame = Frame(master, relief=GROOVE, borderwidth=3)
        runtimeFrame.pack(fill=X, pady=5, padx=5)
        for mode in ['java', 'python', 'jython']:
            b = Radiobutton(runtimeFrame, text=mode, variable=self.radio_var, value=mode, indicatoron=1)
            b.pack(side=LEFT)

if __name__ == '__main__':
    master = Tk()
    app = App(master)
    mainloop()

注意一个细微的变化

app = App(master)

这是必需的,以便应用程序实例不会过早地被垃圾收集.这将有效地将 self.radio_var 拉出范围,我们又回到了第一个.

This is required so that the App instance is not garbage collected prematurely. This would effectively pull the self.radio_var out of scope and we're back at square one.