Here is some example code that creates 4 Radiobutton
s, 2 using int
and 2 using 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()
After running this I have a box that look like this:
For some reason the str
ones start selected while the int
ones do not. Is there a reason for this? Is there any fix for it? I know I could work around it by just using number values and then converting them to strings but I'd like to understand why this is happening first.
I am using Windows 10 if that matters.
Edit: for clarification, the buttons still work properly after they have been clicked on.
In the case of the second set of radiobuttons, they are being rendered in "tri-state mode".
According to the official documentation1:
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.
The default for tristatevalue
is the empty string, and the default value for a StringVar
is the empty string. For your second set of radiobuttons both the variable value and the tristatevalue
are the same so you are seeing the "tri-state mode".
In the case of the IntVar
, the default value of the variable is zero. The tristatevalue
is still the empty string. Those two are different so the widget does not appear in "tri-state mode".
To prove this, set tristatevalue
to zero for the first set of radiobuttons so that it matches the default value of the associated variable and you will see that their appearance changes to match the second set.
int1 = Radiobutton(..., tristatevalue=0)
int2 = Radiobutton(..., tristatevalue=0)
Likewise, you could set the tristatevalue
of the second set to something other than the default value so that they will look like the first set:
str1 = Radiobutton(..., tristatevalue="x")
str2 = Radiobutton(..., tristatevalue="x")
The best practice with radiobuttons is to always make sure the default value corresponds to one of the radiobutton values, unless you truly do want "tri-state mode".
In your case, you should initialize the variables to the value of one of the radiobuttons:
self.v1 = IntVar(value=1)
self.v2 = StringVar(value="1")
... or after you create them, via set
:
self.v1.set(1)
self.v2.set("1")
1 the link goes to the tcl/tk man pages. Tkinter is just a thin wrapper around tcl/tk, and this documentation is the definitive answer to how the widgets behave.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With