¿Cómo obtengo el valor del Radiobutton seleccionado en tkinter?
Un Radiobutton no sabe que los demás existen. Lo que los agrupa es una sola variable de Tk compartida por todos los botones del grupo, cada uno con su propio value, y la respuesta se lee de esa variable, nunca de los botones.
import tkinter as tk
root = tk.Tk()
size = tk.StringVar(value="medium") # el grupo *es* esta variable
for label in ("small", "medium", "large"):
tk.Radiobutton(root, text=label.title(), variable=size, value=label).pack(anchor="w")
def order():
print("eligió", size.get()) # lee la variable, no los botones
tk.Button(root, text="Pedir", command=order).pack()
root.mainloop() Por qué se ven todos marcados a la vez
Son dos errores distintos. El primero es crear una variable nueva para cada botón, casi siempre un tk.IntVar() dentro del bucle que los construye. Cada botón pasa a ser un grupo de uno, y un grupo de uno siempre muestra su propia selección, así que se marcan todos juntos.
El segundo es compartir la variable pero no poner value en los botones. Un Radiobutton sin valor tiene la cadena vacía como valor, así que al pulsar cualquiera la variable queda en la cadena vacía, que es justo lo que están mirando todos los demás. Cada botón necesita un valor distinto.
# mal: una variable nueva por botón, cada uno es su propio grupo
for i, label in enumerate(("small", "medium", "large")):
v = tk.IntVar()
tk.Radiobutton(root, text=label, variable=v, value=i).pack()
# mal: variable compartida, pero todos con el mismo valor vacío
tk.Radiobutton(root, text="Small", variable=size).pack()
tk.Radiobutton(root, text="Large", variable=size).pack()Por qué dos grupos que no tienen relación se pelean
No poner variable no vuelve independientes a los botones, y esa suposición es lo que hace tan confuso este caso. Todos caen en un único grupo que Tk proporciona por defecto, llamado selectedButton, así que un grupo de tallas y otro de formas de pago en la misma ventana se desmarcan entre sí y parece que tkinter olvidara la elección.
Una variable por grupo es toda la solución. La variable es el grupo, así que dos grupos son dos variables, y cada botón tiene que nombrar aquella a la que pertenece.
size = tk.StringVar(value="medium")
payment = tk.StringVar(value="card")
tk.Radiobutton(root, text="Small", variable=size, value="small")
tk.Radiobutton(root, text="Large", variable=size, value="large")
tk.Radiobutton(root, text="Card", variable=payment, value="card")
tk.Radiobutton(root, text="PayPal", variable=payment, value="paypal")Reaccionar en cuanto eligen
Un command se ejecuta en cada clic, después de que la variable se actualizó, así que puede llamar a .get() de inmediato y actuar sobre la respuesta. Así se muestra un precio, se habilita un campo o se cambia parte de la ventana según la elección.
Ponle el mismo command a todos los botones del grupo. No recibe ningún argumento que diga cuál se pulsó, y no lo necesita, porque la variable ya tiene la respuesta.
def on_choice():
print("ahora", size.get())
tk.Radiobutton(root, text="Large", variable=size, value="large", command=on_choice)Empezar sin ninguno seleccionado
Dale a la variable un valor que ningún botón use. Un StringVar vacío ya lo hace solo, y esa es la razón principal para preferirlo aquí sobre un IntVar: tk.IntVar() empieza en 0, así que un botón con valor 0 aparece ya seleccionado, lo hayas querido o no.
Lo mismo sirve para reiniciar el grupo más tarde. size.set("") borra la selección y size.set("large") mueve el punto desde el código, sin ningún clic.
size = tk.StringVar() # nada seleccionado al principio
size.set("large") # seleccionar Large desde el código
size.set("") # volver a dejarlo sin selecciónTextos o números como valores
Las dos cosas funcionan, pero el valor es lo que tu manejador va a tener que interpretar después, así que un StringVar con "large" se entiende mejor en el punto de uso que un IntVar con 2, y además sobrevive a que alguien reordene los botones. Usa números cuando el valor sea de verdad un número con el que vas a calcular.
Hacerlo sin buscarlo
Coloca los radio buttons y dales el mismo nombre en Group (variable) en el inspector, con un Value distinto cada uno. La exportación escribe un StringVar por cada nombre de grupo y conecta a él todos los botones de ese grupo, así que ninguno de los dos errores de arriba es posible: dos grupos reciben dos variables porque tienen dos nombres.
Diseña la ventana visualmente y ve el código Python generado sobre la marcha.
Abrir el diseñador de tkinter →