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的图形界面开发?
顺便说一下:我用的是python 2.7
6 个回答
2
我知道这已经过去很久了,但我试过这里提到的很多方法,都没能解决我的问题。对我有效的办法就是简单地“重写”鼠标移动事件的处理函数。这不是一个完美的解决方案,因为我在终端上打印了一些奇怪的东西,但在我这个特定的情况下,这并不是问题。
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())) )
附注:你不需要重写所有的函数,只重写其中一个就足够了。
4
试试这个,这对我有效。
v = 0 # this is global variable
def some_function():
global v
v = IntVar()
v.set(0)
rb1 = Radiobutton (parent, variable = v, value = 0)
rb1.pack()
rb2 = Radiobutton (parent, variable = v, value = 1)
rb2.pack()
先做出你的单选按钮,然后你就能得到应该有的单选按钮效果。
14
你存储变量对象(在你的例子中是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超出作用域,我们又回到了最初的问题。