Tkinter单选按钮初始化错误

时间:2011-02-21 21:37:30

标签: python tkinter

如果我在一个功能中放一个单选按钮并绘制它们;它们第一次被绘制时,你不能将它们悬停在它们之上,而不会让它们看起来像是被选中。

函数中的相同代码不会出现此行为。

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

一旦你做出选择,这不会再发生。 难道我做错了什么?是否有解决方法,因为我的代码必须在函数中!

这是我在Tkinter找到的第二个基本错误。 Python GUI开发有什么更好的东西吗?

ps:我正在使用python 2.7

5 个答案:

答案 0 :(得分:10)

存储变量对象的位置(StringVar,v,在您的情况下)必须保持不变,以便这种奇怪的行为不会出现。我的猜测是我们看到这种行为因为v超出了范围,出现了问题。除了使用全局之外,我无法想到从函数中执行此操作的方法。

代码破碎:

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

考虑一下,如果你有多个需要持久存储的变量,你可以传入一个变量列表或字典。

另外,如果“必须在函数中”是作业分配要求,请考虑将代码包装在类中。我不是tk专家,但这似乎是组织代码的首选方式。

示例修复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)

这是必需的,以便App实例不会过早地进行垃圾回收。这将有效地将self.radio_var拉出范围,我们又回到了第一个方位。

答案 1 :(得分:1)

我知道这花了很多时间,但我已经尝试过这里显示的所有策略,但没有一个能与我合作。对我有用的是简单的“重写”鼠标运动事件的事件处理程序。这不是一个完美的解决方案,因为我在终端上打印了一些垃圾,但在我的特殊情况下,这不是问题。

server_name = IntVar()
server_name.set(1)
server_name_rb_1 = Radiobutton(container_3, text="Server", variable=server_name, value=1)
server_name_rb_1.select()
server_name_rb_1.pack()
server_name_rb_2 = Radiobutton(container_3, text="Local", variable=server_name, value=2)
server_name_rb_2.deselect()
server_name_rb_2.pack()

server_name_rb_2.bind('<Motion>',lambda e: print(str(server_name.get())) )

P.S。:您不需要重写所有功能只需重写其中一个必须足够。

答案 2 :(得分:0)

我只需将 state = NORMAL,添加到所有单选按钮即可解决此问题。我很欣赏这是默认行为,但看起来像是tkinter有点不记得了。

答案 3 :(得分:-1)

我承认你发现了一个奇怪的“故障”。我并没有完全准备把它称为故障,因为我不确定是什么导致它。它似乎源于变量,参数。解决方法是获取变量,而不是通过 .cget('text')方法获取窗口小部件的实际文本。

我对您的应用功能的更改:

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, value=mode, indicatoron = 1 ) # I omitted the variable argument, which seemed to be the root of your troubles. 
        b.pack(side = LEFT)
        b.deselect() # manually deselects each instance of the Radiobutton. 

    b.select() # manually selects a default instance of the Radiobutton. 

答案 4 :(得分:-1)

试试这个,它对我有用。

<input type="checkbox" />
<div>
  <img class="dropPillow" src="https://image.freepik.com/free-icon/square-outlined-shape_318-75498.png">
</div>

制作你的收音机按钮,然后你就可以得到它们的单选按钮。