How to select only one Radiobutton in tkinter - python

I have two radiobutton in my GUI but i want to able select only one at a time with the code below am able to select both radiobutton . I tried the checkbutton which also i can select both options.
from tkinter import *
def content():
if not option1.get() and not option2.get():
print("not allowed, select one dude")
else:
print("welcome dude")
option1.set(False)
option2.set(False)
root = Tk()
root.geometry("400x400")
option1 = BooleanVar(value=False)
R1 = Radiobutton(root, text="MALE", value=1, var=option1)
R1.pack()
option2 = BooleanVar(value=False)
R2 = Radiobutton(root, text="FEMALE", value=2, var=option2)
R2.pack()
b = Button(root, text="print", command=content)
b.pack(side="bottom")
root.mainloop()

You must bind both radiobuttons to the same variable.
Besides, the variable will receive the value specified in the value keyword argument.
I suggest you do the following:
option = StringVar()
R1 = Radiobutton(root, text="MALE", value="male", var=option)
R2 = Radiobutton(root, text="FEMALE", value="female", var=option)
You can know what item is currently selected, by tracing the option variable, and by calling its get method.
For instance, the following will print either "male" or "female" whenever the corresponding radiobutton is checked.
def print_var(*_):
print(option.get())
root = Tk()
root.geometry("400x400")
option = StringVar()
R1 = Radiobutton(root, text="MALE", value="male", var=option)
R2 = Radiobutton(root, text="FEMALE", value="female", var=option)
R1.pack()
R2.pack()
option.trace('w', print_var)
root.mainloop()
A more complete example, according to your demand.
This script will display a window with two radiobuttons and a button.
When the button is clicked, a message is printed that depends upon whether an option was selected or not.
from tkinter import *
def validate():
value = option.get()
if value == "male":
print("Welcome dude")
elif value == "female":
print("Welcome gurl")
else:
print("An option must be selected")
root = Tk()
root.geometry("400x400")
option = StringVar()
R1 = Radiobutton(root, text="MALE", value="male", var=option)
R2 = Radiobutton(root, text="FEMALE", value="female", var=option)
button = Button(root, text="OK", command=validate)
R1.pack()
R2.pack()
button.pack()
root.mainloop()
As a side note, you should never import a module with a star, eg from tkinter import *.
In short, it pollutes the namespace. More on this post.

I presume you are wanting to create one radio button with multiple values which only allows one selection? You would be better to populate an array and run a loop to fill the radio button. Perhaps something like this?
from tkinter import *
root = Tk()
root.geometry("400x400")
GENDERS = [
("Male", "M"),
("Female", "F"),
("Other", "O")
]
v = StringVar()
v.set("L") # initialize
for text, gender in GENDERS:
b = Radiobutton(root, text=text,
variable=v, value=gender)
b.pack(anchor=W)
root.mainloop()

The easiest way to do it that i found is this -
you have to give them both the same variable so that compiler can know that the user can only choose one...
from tkinter import *
window = Tk()
window.geometry("100x100")
var = IntVar()
radio = Radiobutton(window, text="this", variable=var, value=1)
radio.pack()
radio2 = Radiobutton(window, text="or this", variable=var, value=2)
radio2.pack()
window.mainloop()

Related

How do I get the value from radiobuttons?

So I'm trying to make a program in python tkinter that creates 3 radiobuttons for different difficulties for the user to choose. I created a variable diffLevel = IntVar() and I'm trying to change it using those radiobuttons. Then, when the user has chosen the difficulty, he presses a button that activates a command that tries to read the value of diffLevel and does different commands depending on its value. But, for some reason, it doesn't work. Here is the code:
win = Tk()
win.geometry('250x250+650+250')
diffLevel = IntVar()
diffChoiceE = Radiobutton(win, text="Easy", variable=diffLevel, value=0)
diffChoiceE.place(x=10, y=10)
diffChoiceM = Radiobutton(win, text="Medium", variable=diffLevel, value=1)
diffChoiceM.place(x=10, y=35)
diffChoiceH = Radiobutton(win, text="Hard", variable=diffLevel, value=2)
diffChoiceH.place(x=10, y=60)
def diffSet():
a = diffLevel.get()
if a == 0:
setSpades()
elif a == 1:
setSpades()
setHearts()
elif a == 2:
setSpades()
setHearts()
setClubs()
setDiamonds()
win.destroy()
ch = Button(win, text="Choose", width=7, height=1, command=diffSet)
ch.place(x=100, y=80)
win.mainloop()
I tried printing 'a', but for some reason, it says '0', even though I selected the radiobutton that makes diffLevel equal 1 or 2. I tried using the ttk module, but then the radiobuttons don't work and all act as if they were pressed. So how can I get the correct value from diffLevel?
I have changed the code a little bit to run on my computer but it seems that the code is working appropriately for me.
win = Tk()
win.geometry('250x250+650+250')
diffLevel = IntVar()
diffChoiceE = Radiobutton(win, text="Easy", variable=diffLevel, value=0)
diffChoiceE.place(x=10, y=10)
diffChoiceM = Radiobutton(win, text="Medium", variable=diffLevel, value=1)
diffChoiceM.place(x=10, y=35)
diffChoiceH = Radiobutton(win, text="Hard", variable=diffLevel, value=2)
diffChoiceH.place(x=10, y=60)
def diffSet():
a = diffLevel.get()
print('Values of a: ',a)
if a == 0:
print('Spades')
elif a == 1:
print('Spades&Hearts')
elif a == 2:
print('Spades&Hearts&Clubs&Diamonds')
#win.destroy()
ch = Button(win, text="Choose", width=7, height=1, command=diffSet)
ch.place(x=100, y=80)
win.mainloop()
I have selected each radio button and they are all working currently printing:
Values of a: 0
Spades
Values of a: 1
Spades&Hearts
Values of a: 2
Spades&Hearts&Clubs&Diamonds
I am using python 3.7 and TkVersion 8.6. Which version are you using ?

How to enable a disabled Button after filling Entry widgets?

I have 2 Entrys and one button. I want to make that button's state disabled until the two Entrys are filled in. How can I achieve that?
howManyStocksLabel = Label(root, text = "How many stocks do you want to evaluate?")
howManyStocksLabel.grid(row = 1, column = 0)
howManyStocksEntry = Entry(root, borderwidth = 3)
howManyStocksEntry.grid(row = 1, column = 1)
riskLabel = Label(root, text = "Enter risk %")
riskLabel.grid(row = 2, column = 0, sticky = 'w')
riskEntry = Entry(root, borderwidth = 3)
riskEntry.grid(row = 2, column = 1)
nextButton = Button(root, text = "Next!", width = 20, height = 2,state = DISABLED,
fg = 'green', bg = 'white',
command= lambda: myClick(riskEntry, howManyStocksEntry, var))
nextButton.grid(row = 4, column = 1)
I tried to check whether the entries are filled in or not by:
if(riskEntry.get() != ""):
....................
but it just doesn't work.
You need to check if the value is there after the user inputs it. Also, you can use tk.StringVar() as a text variable and trace it.
Here is an example:
import tkinter as tk
def check_entry(*args):
if r1.get() and r2.get():
b1.config(state='normal')
else:
b1.config(state='disabled')
root = tk.Tk()
r1 = tk.StringVar(master=root)
r2 = tk.StringVar(master=root)
e1 = tk.Entry(root, textvariable=r1)
e1.pack()
e2 = tk.Entry(root, textvariable=r2)
e2.pack()
b1 = tk.Button(root, text='Click Me!', state='disabled')
b1.pack()
r1.trace('w', check_entry)
r2.trace('w', check_entry)
root.mainloop()
You will need to use a binding on your entry widgets to check whether the user has entered anything into the entry or not.
This code will fire the check_entry function every time the user types in one of the entry boxes:
riskEntry.bind('<KeyRelease>', check_entry)
howManyStocksEntry.bind('<KeyRelease>', check_entry)
Then your check_entry function might look like this:
def check_entry(event): #event is required for all functions that use a binding
if riskEntry.get() and howManyStocksEntry.get():
nextButton.config(state=NORMAL)
else:
nextButton.config(state=DISABLED)
One way to do it would be to utilize the ability to "validate" their contents that Entry widgets support — see adding validation to an Entry widget — but make it check the contents of multiple Entry widgets and change the state of a Button accordingly.
Below shows how to do this via a helper class that encapsulates most of the messy details needed to make doing it relatively painless. Any number of Entry widgets can be "watched", so it scales well to handle forms consisting of many more than merely two entries.
from functools import partial
import tkinter as tk
from tkinter.constants import *
class ButtonEnabler:
""" Enable/disable a Button depending on whether all specified Entry widgets
are non-empty (i.e. contain at least one character).
"""
def __init__(self, button, *entries):
self.button = button
self.entries = entries
for entry in self.entries:
func = root.register(partial(self.check_entries, entry))
entry.config(validate="key", validatecommand=(func, '%P'))
def check_entries(self, this_entry, new_value):
other_entries = (entry for entry in self.entries if entry is not this_entry)
all_others_filled = all(entry.get() for entry in other_entries)
combined = bool(new_value) and all_others_filled
self.button.config(state=NORMAL if combined else DISABLED)
return True
root = tk.Tk()
howManyStocksLabel = tk.Label(root, text="How many stocks do you want to evaluate?")
howManyStocksLabel.grid(row=1, column=0)
howManyStocksEntry = tk.Entry(root, borderwidth=3)
howManyStocksEntry.grid(row=1, column=1)
riskLabel = tk.Label(root, text="Enter risk %")
riskLabel.grid(row=2, column=0, sticky='w')
riskEntry = tk.Entry(root, borderwidth=3)
riskEntry.grid(row=2, column=1)
nextButton = tk.Button(root, text="Next!", width=20, height=2, state=DISABLED,
fg='green', bg='white', disabledforeground='light grey',
command=lambda: myClick(riskEntry, howManyStocksEntry, var))
nextButton.grid(row=4, column=1)
enabler = ButtonEnabler(nextButton, howManyStocksEntry, riskEntry)
root.mainloop()

Python Tk _tkinter.TclError: invalid command name ".42818376"

I am getting the error mentioned in the title of the post I really just want this to work. Been working on this problem for a while now and it is frustrating. My ultimate goal is to obtain the values for the varables text, chkvar, and v.
Thanks to anyone who can reply and help on this!!
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
def killwindow():
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = ""
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
tk1 = text.get(text)
tk2 = chkvar.get(chkvar)
tk3 = v.get(v)
print tk1
print tk2
print tk3
Once mainloop exits, the widgets no longer exist. When you do text.get(text), you're trying to access a deleted widget. Tkinter simply isn't designed to allow you to access widgets after the main window has been destroyed.
The quick solution is to modify killwindow to get the values before it destroys the window, and store them in a global variable which you can access after mainloop exits.
The program didn't make it through the variable getting, so it never reported the incorrect method calls. I made a few changes to the original code (added a textval StringVar, and changed the v variable to another IntVar). I had a feeling the "associated variables" wouldn't have a problem, and didn't need to be included in the killwindow code. The only variable I grab in killwindow is the text data.
Working code (changed lines marked with #++) :
#!C:/Python27/python.exe
from Tkinter import *
import ImageTk, Image
root = Tk()
root.title('HADOUKEN!')
textval = StringVar() #++ added
def killwindow():
textval.set(text.get('1.0',END)) #++ grab contents before destruction
root.destroy()
text = Text(root, height=16, width=40)
scroll = Scrollbar(root, command=text.yview)
text.configure(yscrollcommand=scroll.set)
text.grid(sticky=E)
scroll.grid(row=0,column=1,sticky='ns')
text.focus()
chkvar = IntVar()
chkvar.set(0)
c = Checkbutton(root, text="CaseIt", variable=chkvar)
c.grid(row=1,column=0,sticky=W)
v = IntVar() #++ changed
v.set(1) #++ initial value
radio1 = Radiobutton(root, text="Src", variable=v, value=1)
radio1.grid(row=1,column=0)
radio1.focus()
radio2 = Radiobutton(root, text="Dst", variable=v, value=2)
radio2.grid(row=2,column=0)
b1 = Button(root, text="Submit", command=killwindow)
b1.grid(row=1, column=2)
img = ImageTk.PhotoImage(Image.open("Hadoken.gif"))
panel = Label(root, image = img)
panel.grid(row=0, column=2)
root.mainloop()
# windows are destroyed at this point
tk1 = textval.get() #++ changed
tk2 = chkvar.get() #++ changed
tk3 = v.get() #++ changed
print tk1
print tk2
print tk3

Need assistance Tkinter in Python 2.7

I am writing a subnetting program in Python and I have come across a problem.
So far everything is working minus one thing. I dont know how to change a label in a method. in the code below, SubnetM is the variable being used to show the subnet mask. It is set to 0 by default but when you select HOSTS and enter 6 as Quantity. The 0 does not change to 255.255.255.248. PLEASE HELP
from Tkinter import *
SubnetM = 0
def beenclicked():
radioValue = relStatus.get()
return
def changeLabel():
if radio1 == 'HOSTS':
if Quantity == 6:
SubnetM = "255.255.255.248"
return
app = Tk()
app.title("SUBNET MASK CALCULATOR")
app.geometry('400x450+200+200')
labelText = StringVar()
labelText.set("WELCOME!")
label1 = Label(app,textvariable=labelText, height=4)
label1.pack()
relStatus = StringVar()
relStatus.set(None)
radio1 = Radiobutton(app, text="HOSTS", value="HOSTS", variable=relStatus, command=beenclicked).pack()
radio1 = Radiobutton(app, text="NETWORKS", value="NETWORKS", variable=relStatus, command=beenclicked).pack()
label2Text = StringVar()
label2Text.set("~Quantity~")
label2 = Label(app, textvariable=label2Text, height=4)
label2.pack()
custname = IntVar(None)
Quantity = Entry(app,textvariable=custname)
Quantity.pack()
label3Text = StringVar()
label3Text.set("Your Subnet Mask is...")
label3 = Label(app, textvariable=label3Text, height=4)
label3.pack()
label4Text = StringVar()
label4Text.set(SubnetM)
label4 = Label(app, textvariable=label4Text, height=4)
label4.pack()
button1 = Button(app, text="GO!", width=20, command=changeLabel)
button1.pack(padx=15, pady=15)
app.mainloop()
To fix your problem, make changeLabel like this:
def changeLabel():
# Get the radiobutton's StringVar and see if it equals "HOSTS"
if relStatus.get() == 'HOSTS':
# Get the entrybox's IntVar and see if it equals 6
if custname.get() == 6:
# Set the label's StringVar to "255.255.255.248"
label4Text.set("255.255.255.248")
Also, the .pack method of a Tkinter widget returns None. So, you should make the part that defines the radiobuttons like this:
radio1 = Radiobutton(app, text="HOSTS", value="HOSTS", variable=relStatus, command=beenclicked)
radio1.pack()
radio2 = Radiobutton(app, text="NETWORKS", value="NETWORKS", variable=relStatus, command=beenclicked)
radio2.pack()

Radiobuttons are modifying wrong values tkinter

I am working on a script with tkinter, but something weird is happening.
I have two radioButtons:
way=False
RadioButton0=Radiobutton(root,text="From",variable=way,value=False)
RadioButton1=Radiobutton(root,text="To",variable=way,value=True)
RadioButton0.grid(column=0,row=2)
RadioButton1.grid(column=1,row=2)
And a text entry field:
entryValue=0
entryField=Entry(root,textvariable=entryValue)
entryField.grid(column=0,row=4)
When I enter 0 in entry field, RadioButton0 is automatically selected, when I enter 1, RadioButton1 is selected and for any other value, they both get selected...
This works vice versa: when I select RadioButton0, entry field changes to 0 and when I select RadioButton1, entry field changes to 1... Also, entryValue is later seen as 0. Variable way should only be modified by radio buttons...
Why is that happening? Am I doing something I shouldn't? And how do I fix it?
variable and textvariable should be both different variable objects, not just built-in data types:
way=BooleanVar(root)
way.set(False)
# ...
entryValue=StringVar(root)
entryValue.set("0")
you can use a command to call a method and set the value. Please refer attached code.
def sel():
selection = "You selected the option " + str(var.get())
label.config(text = selection)
root = Tk()
frame = Frame(root)
frame.pack()
labelframe = LabelFrame(frame, text="This is a LabelFrame")
labelframe.pack(fill="both", expand="yes")
var = IntVar()
R1 = Radiobutton(labelframe, text="Option 1", variable=var, value=1,
command=sel)
R1.pack( anchor = W )
R2 = Radiobutton(labelframe, text="Option 2", variable=var, value=2,
command=sel)
R2.pack( anchor = W )
R3 = Radiobutton(labelframe, text="Option 3", variable=var, value=3,
command=sel)
R3.pack( anchor = W)
label = Label(labelframe)
label.pack()

Categories