Tkinter 单选按钮初始化错误 [英] Tkinter radio button initialization bug

查看:25
本文介绍了Tkinter 单选按钮初始化错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在函数中放置一个单选按钮并绘制它们;第一次绘制它们时,您不能将鼠标悬停在它们上面而不使它们看起来都被选中.

If I put a radio button in a function and draw them; the first time they are drawn you cannot hover over them without making them look like they are all selected.

函数中的相同代码不会表现出这种行为.

The same code out of a function does not exhibit this behaviour.

from Tkinter import *

def App(master):
    v = StringVar()
    v.set('python') # initialize
    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)

    #The following code chunk is the same as that in App()
    #------------------------
    v = StringVar()
    v.set('python') # initialize
    lable1 = Label(master, text=' hovering over below radio buttons will cause them to Not look selected as expected')
    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)
    #------------------------

    mainloop() 

一旦您做出选择,这种情况就不会再发生.难道我做错了什么?有没有解决方法,因为我的代码必须在一个函数中!

Once you have made a selection this does not happen again. Am I doing something wrong? Is there a workaround, because my code has to be in a function!

这是我在 Tkinter 中发现的第二个基本错误.Python GUI 开发有什么更好的方法吗?

This is the second elementary bug I have found in Tkinter. Is there something better for Python GUI development?

ps:我使用的是 python 2.7

ps: I'm using python 2.7

推荐答案

您存储变量对象(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.

这篇关于Tkinter 单选按钮初始化错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆