Determining what radiobutton was selected tkinter - python

I am trying to figure out how to use tkinter radio-buttons properly.
I have used this question as a guideline: Radio button values in Python Tkinter
For some reason I can't figure out how to return a variable that is indicative of what the user selected.
Code:
def quit_loop():
global selection
selection = option.get()
root.quit()
return selection
def createWindow():
root = Tk()
root.geometry=('400x400')
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option)
button = Button(root, text='ok', command=quit_loop)
R1.pack()
R2.pack()
button.pack()
root.mainloop()
when I call createWindow() I would expect the radio-button box to pop up, and after making my selection and pressing 'ok' I expected it to return me a variable selection which relates to the selected button. Any advice? Tkinter stuff is particularly challenging to me because it seems so temperamental.

You need to make option global if you want to access outside of createWindow
Here's an example of your code that will print out the value of the selected radiobutton and then quit when you click the button. I simply had to declare root and options as global:
from tkinter import *
def quit_loop():
global selection
selection = option.get()
root.quit()
return selection
def createWindow():
global option, root
root = Tk()
root.geometry=('400x400')
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option)
button = Button(root, text='ok', command=quit_loop)
R1.pack()
R2.pack()
button.pack()
root.mainloop()
createWindow()

As far as I know one needs to do two things to communicate with tkinter
widgets: pass a variable, and pass a command. When user interacts with
widgets, tkinter will do two things: update value of variable and call the
function passed in as command. It is up to us to access the value of the
variable inside the command function.
import tkinter as tk
from tkinter import StringVar, Radiobutton
def handle_radio():
print(option.get())
root = tk.Tk()
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option, command=handle_radio)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option, comman=handle_radio)
R1.pack()
R2.pack()
root.mainloop()
The code prints 'Create' and 'Compile' when user selects the appropriate
radio option.
Hope this helps.
Regards,
Prasanth

Related

Why is my Label not disappearing when i call the .place_forget() method?

I am writing a an application and it has a function where when "yes" is selected in a ListBox, it runs code that places a label. When I used the .place_forget() method or even the .place() method to move it off screen, I get two versions of the Label or it doesn't move at all and I am very confused as to why.
#dropdown event handling
def selected(event):
entrydisplay = clicked.get()
if 'Yes' in entrydisplay:
global extrainfo
extrainfo = tk.Entry(root, width=32)
extrainfo.place(x=312,y=201)
extra_label = tk.Label(root, text='If yes, what team and level of FIRST?', width=28, height=1, bg='red3', fg='black')
extra_label.place(x=110, y=200)
interest_label.place(x=130,y=230)
interest_mechanical.place(x=311, y=228)
interest_electrical.place(x=311, y=248)
interest_marketing.place(x=311, y=268)
interest_design.place(x=311, y=288)
interest_programming.place(x=311, y=308)
interest_chairmans.place(x=311, y=328)
interest_advocacy.place(x=311, y=348)
interest_leadership.place(x=311, y=368)
interest_video_production.place(x=311, y=388)
interest_social_media.place(x=311, y=408)
other_checkbox.place(x=311, y=428)
check_box_move = "0"
if 'No' in entrydisplay:
check_box_move = "1"
def Clear():
name.delete(0, END)
email.delete(0, END)
clicked.set(options[2])
grade.delete(0, END)
interest_mechanical.deselect()
interest_electrical.deselect()
interest_marketing.deselect()
interest_design.deselect()
interest_programming.deselect()
interest_chairmans.deselect()
interest_advocacy.deselect()
interest_leadership.deselect()
interest_social_media.deselect()
interest_video_production.deselect()
other_checkbox.deselect()
extrainfo.delete(0, END)
other_entry.delete(0,END)
other_entry.place(x=798, y=400)
extrainfo.place(x=798, y=201)
extra_label.destroy()
Here's a version I wrote so you could replicate my issue:
from tkinter import *
import tkinter as tk
root = Tk()
root.geometry("400x400+0+0")
root.title("test")
def selected(event):
global test_label
test_label = tk.Label(root, text='TEST')
test_label.place(x=20,y=20)
def Delete():
test_label.destroy
#DROPDOWN BASE CODE
options = [
'Yes',
'No',
'Select'
]
clicked = StringVar()
clicked.set(options[2])
#ENDS ABOVE
Dropdown = tk.OptionMenu(root, clicked, *options, command=selected)
Dropdown.place(x=311, y=165)
delete_button = tk.Button(root, text='Click to delete text', command=Delete)
delete_button.place(x=100,y=100)
root.mainloop()
The problem is quite related to global and local scopes. When you define a variable inside of a function it is only defined within that function and for it to be able to be discovered by other functioon you have to make it available to the global scope. Simply say, global extra_label for it to be defined in the other functions too.
Hope it cleared your doubt and error.
Cheers
If you don't want that label at all then you can use destroy() method to permanently delete the Label from your application. Also you should specify what kind of app you are building to make your question more clear.

Updating label keeps previous text

In the program I made, the user presses enter and the text typed is then shown as a label in the program. So the label keeps getting updated and then written on the next line. The problem is that in the textbox the previous line the user typed stays there, which means u have to keep manually deleting the string in the textbox to write a new line. How can I make it so that you start out with a cleared textbox? Also, the enter button works but it seems that when i click on the "Return" button it gives me an error:
TypeError: evaluate() missing 1 required positional argument: 'event'
Here's the code:
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b= Button(window, text="Return", command=evaluate)
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Since you bind evaluate as a callback and you use it as a button command, when you use it in the button you have to use a lambda and pass None to the event. event argument is needed because of the binding, but there is no event when you call it from button click, so just pass None to get rid of the error. You can delete by doing entry.delete(0, 'end').
from tkinter import *
window = Tk()
window.geometry("200x300")
def evaluate(event):
thetext = StringVar()
labeloutput = Label(app, textvariable = thetext)
n = e.get()
thetext.set(n)
labeloutput.grid()
e.delete(0, 'end') # Here we remove text inside the entry
app = Frame(window)
app.pack()
e = Entry(window)
e.pack()
b = Button(window, text="Return", command=lambda: evaluate(None)) # Here we have a lambda to pass None to the event
b.pack()
window.bind("<Return>", evaluate)
mainloop()
Of course, if you want to prevent the lambda from being used, you would have to create a function to handle the key binding, and a separate one for the button click.

Entry data manipulation difficulties [duplicate]

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

Tkinter checkbutton menu doesn't show check indicator

When I create a Tkinter menu that includes checkbuttons I can't see the indicator when an item has been clicked. I should see something like this :
However I don't see the little check.
I'm on OS X if this is linked.
Using this code for example who works for someone else :
from tkinter import *
master = Tk()
var = StringVar(master)
var.set("Check")
w = OptionMenu(master, variable = var, value="options:")
w.pack()
first = BooleanVar()
second = BooleanVar()
third = BooleanVar()
w['menu'].add_checkbutton(label="First", onvalue=True, offvalue=False, variable=first)
w['menu'].add_checkbutton(label="Second", onvalue=True, offvalue=False, variable=second)
w['menu'].add_checkbutton(label="Third", onvalue=1, offvalue=False, variable=third)
master.bind('<Button-1>', lambda x: print("First:", first.get(), " - Second:", second.get(), " - Third:", third.get()))
mainloop()
UPDATE
If I set up a Menu widget (not an OptionMenu) then I'll be able to see the little checks. So this only doesn't work for OptionMenu widgets and MenuButton widgets

.get() not giving a value [duplicate]

I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()

Categories