为什么 Tkinter 的单选按钮在使用 StringVar 而不是 IntVar 时都开始选中?
Why do Tkinter's Radio Buttons all Start Selected When Using StringVar but not IntVar?
下面是一些示例代码,它创建了 4 个 Radiobutton
,其中 2 个使用 int
,2 个使用 str
:
from tkinter import *
class test:
def __init__(self):
wind = Tk()
frame1 = Frame(wind)
frame1.pack()
self.v1 = IntVar()
self.v2 = StringVar()
int1 = Radiobutton(frame1, text = 'int1', variable = self.v1, value = 1,
command = self.ipress)
int2 = Radiobutton(frame1, text = 'int2', variable = self.v1, value = 2,
command = self.ipress)
str1 = Radiobutton(frame1, text = 'str1', variable = self.v2, value = '1',
command = self.spress)
str2 = Radiobutton(frame1, text = 'str2', variable = self.v2, value = '2',
command = self.spress)
int1.grid(row = 1, column = 1)
int2.grid(row = 1, column = 2)
str1.grid(row = 2, column = 1)
str2.grid(row = 2, column = 2)
str1.deselect() #this didn't fix it
str2.deselect()
def ipress(self):
print('int'+str(self.v1.get()))
def spress(self):
print('str'+self.v2.get())
test()
在 运行 之后我有一个看起来像这样的盒子:
出于某种原因,str
开始被选中,而 int
没有。是否有一个原因?有什么解决办法吗?我知道我可以通过使用数字值然后将它们转换为字符串来解决它,但我想了解为什么会先发生这种情况。
如果重要的话,我正在使用 Windows10。
编辑: 澄清一下,按钮在单击后仍然可以正常工作。
对于第二组单选按钮,它们在 "tri-state mode" 中呈现。
If the variable's value matches the tristateValue, then the
radiobutton is drawn using the tri-state mode. This mode is used to
indicate mixed or multiple values.
说明
tristatevalue
的默认值是空字符串,StringVar
的默认值是空字符串。对于第二组单选按钮,变量值和 tristatevalue
都相同,因此您看到的是 "tri-state mode".
在IntVar
的情况下,变量的默认值为零。 tristatevalue
仍然是空字符串。这两个不同,因此小部件不会出现在 "tri-state mode".
中
为了证明这一点,将第一组单选按钮的 tristatevalue
设置为零,使其与关联变量的默认值匹配,您将看到它们的外观发生变化以匹配第二组。
int1 = Radiobutton(..., tristatevalue=0)
int2 = Radiobutton(..., tristatevalue=0)
同样,您可以将第二组的 tristatevalue
设置为默认值以外的其他值,以便它们看起来像第一组:
str1 = Radiobutton(..., tristatevalue="x")
str2 = Radiobutton(..., tristatevalue="x")
解决方案
单选按钮的最佳做法是始终确保默认值对应于其中一个单选按钮值,除非您真的想要 "tri-state mode"。
在您的情况下,您应该将变量初始化为单选按钮之一的值:
self.v1 = IntVar(value=1)
self.v2 = StringVar(value="1")
... 或者在您创建它们之后,通过 set
:
self.v1.set(1)
self.v2.set("1")
1 link 转到 tcl/tk 手册页。 Tkinter 只是 tcl/tk 的薄包装,此文档是小部件行为方式的权威答案。
感谢@Bryan Oakley 的详细解释。
为了简化,
启动后将选中“Sam”单选按钮
self.name = tk.StringVar(value='Sam') ## is like self.name.set('Sam'), will preset the value as "Sam"
name_rad1 = tk.Radiobutton(frame, text='Sam', variable=self.name, value='Sam', command=None)
name_rad1.pack(side=tk.LEFT)
否单选按钮将在启动后被选中
self.name = tk.StringVar(value=' ') ## the value will be " ", when you print(self.name.get())
name_rad1 = tk.Radiobutton(frame, text='Sam', variable=self.name, value='Sam', command=None)
name_rad1.pack(side=tk.LEFT)
下面是一些示例代码,它创建了 4 个 Radiobutton
,其中 2 个使用 int
,2 个使用 str
:
from tkinter import *
class test:
def __init__(self):
wind = Tk()
frame1 = Frame(wind)
frame1.pack()
self.v1 = IntVar()
self.v2 = StringVar()
int1 = Radiobutton(frame1, text = 'int1', variable = self.v1, value = 1,
command = self.ipress)
int2 = Radiobutton(frame1, text = 'int2', variable = self.v1, value = 2,
command = self.ipress)
str1 = Radiobutton(frame1, text = 'str1', variable = self.v2, value = '1',
command = self.spress)
str2 = Radiobutton(frame1, text = 'str2', variable = self.v2, value = '2',
command = self.spress)
int1.grid(row = 1, column = 1)
int2.grid(row = 1, column = 2)
str1.grid(row = 2, column = 1)
str2.grid(row = 2, column = 2)
str1.deselect() #this didn't fix it
str2.deselect()
def ipress(self):
print('int'+str(self.v1.get()))
def spress(self):
print('str'+self.v2.get())
test()
在 运行 之后我有一个看起来像这样的盒子:
出于某种原因,str
开始被选中,而 int
没有。是否有一个原因?有什么解决办法吗?我知道我可以通过使用数字值然后将它们转换为字符串来解决它,但我想了解为什么会先发生这种情况。
如果重要的话,我正在使用 Windows10。
编辑: 澄清一下,按钮在单击后仍然可以正常工作。
对于第二组单选按钮,它们在 "tri-state mode" 中呈现。
If the variable's value matches the tristateValue, then the radiobutton is drawn using the tri-state mode. This mode is used to indicate mixed or multiple values.
说明
tristatevalue
的默认值是空字符串,StringVar
的默认值是空字符串。对于第二组单选按钮,变量值和 tristatevalue
都相同,因此您看到的是 "tri-state mode".
在IntVar
的情况下,变量的默认值为零。 tristatevalue
仍然是空字符串。这两个不同,因此小部件不会出现在 "tri-state mode".
为了证明这一点,将第一组单选按钮的 tristatevalue
设置为零,使其与关联变量的默认值匹配,您将看到它们的外观发生变化以匹配第二组。
int1 = Radiobutton(..., tristatevalue=0)
int2 = Radiobutton(..., tristatevalue=0)
同样,您可以将第二组的 tristatevalue
设置为默认值以外的其他值,以便它们看起来像第一组:
str1 = Radiobutton(..., tristatevalue="x")
str2 = Radiobutton(..., tristatevalue="x")
解决方案
单选按钮的最佳做法是始终确保默认值对应于其中一个单选按钮值,除非您真的想要 "tri-state mode"。
在您的情况下,您应该将变量初始化为单选按钮之一的值:
self.v1 = IntVar(value=1)
self.v2 = StringVar(value="1")
... 或者在您创建它们之后,通过 set
:
self.v1.set(1)
self.v2.set("1")
1 link 转到 tcl/tk 手册页。 Tkinter 只是 tcl/tk 的薄包装,此文档是小部件行为方式的权威答案。
感谢@Bryan Oakley 的详细解释。
为了简化,
启动后将选中“Sam”单选按钮
self.name = tk.StringVar(value='Sam') ## is like self.name.set('Sam'), will preset the value as "Sam"
name_rad1 = tk.Radiobutton(frame, text='Sam', variable=self.name, value='Sam', command=None)
name_rad1.pack(side=tk.LEFT)
否单选按钮将在启动后被选中
self.name = tk.StringVar(value=' ') ## the value will be " ", when you print(self.name.get())
name_rad1 = tk.Radiobutton(frame, text='Sam', variable=self.name, value='Sam', command=None)
name_rad1.pack(side=tk.LEFT)