Los Radiobutton y las variables de control de Tkinter

Los Radiobutton y las variables de control de Tkinter

Los Radiobutton y las variables de control de Tkinter - 100 días de Python #16

En este día aprenderás a manejar los Radiobutton() y las variables de control de Tkinter.

Empecemos por los Radiobutton.

¿Qué es un Radiobutton de Tkinter?

Los Radiobutton son widgets que te permiten crear varias opciones seleccionables en el programa. Son como los <input type=”radio”> de html.

Crear un Radiobutton en Tkinter

Para crear un Radiobutton en Tkinter, lo harás de la siguiente forma:

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

#Radiobutton
Radiobutton(root,
           text="Rojo").pack()

#Bucle de ejecución
root.mainloop()

Esto nos da un Radiobutton() ya seleccionado por defecto.

Vamos a añadir más opciones.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

#Radiobutton
Radiobutton(root,
           text="Rojo").pack()

Radiobutton(root,
           text="Azul").pack()

Radiobutton(root,
           text="Verde").pack()

Radiobutton(root,
           text="Amarillo").pack()

#Bucle de ejecución
root.mainloop()

Ahora hay más opciones, pero salen todas seleccionadas por defecto. Esto no nos sirve para nada de esta forma.

Las variables de control de Tkinter

Las variables de control de Tkinter, son objetos que son capaces de asociar o relacionar diferentes widgets. Un ejemplo de uso de este tipo de objetos es con los Radiobutton().

¿Por qué necesitamos una variable de control con los Radiobutton()?

Los Radiobutton(), están pensados para funcionar en conjunto, es decir, que se muestre, por ejemplo, una pregunta y nos den varias opciones para elegir. De esas opciones, solo se tiene que poder seleccionar una. Para poder hacer lo mismo con varias posibles respuestas a la vez, utilizaremos otro widget, otro día.

Tipos de variables de control

Existen estos cuatro tipos de variables de control en Tkinter:

  • IntVar
  • DoubleVar
  • StringVar
  • BooleanVar

Tal y como ves en sus nombres, se trata de clases (están en PascalCase).

En este capítulo verás ejemplos principalmente de las variables IntVar, las cuales, esperan un valor de tipo int. El resto, las utilizaremos en otra ocasión.

Vamos a crear un objeto de este tipo, para poder relacionar todas las opciones como un conjunto.

Acabo de añadir las líneas 9, 14, 18, 22 y 26. La variable "opcion" instancia un objeto de tipo IntVar(), el cuál, como te he dicho, espera y controlará que se le pase un valor int.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

opcion = IntVar()

#Radiobutton
Radiobutton(root,
           text="Rojo", 
           variable=opcion).pack()

Radiobutton(root,
           text="Azul",
           variable=opcion).pack()

Radiobutton(root,
           text="Verde",
           variable=opcion).pack()

Radiobutton(root,
           text="Amarillo",
           variable=opcion).pack()

#Bucle de ejecución
root.mainloop()

Vamos a darle al primer Radiobutton un value (atributo "valor") de tipo int. Puesto que "Rojo" es la primera opción, le damos un 1.

Al cargar el programa, salen todas las opciones sin marcar. Si le doy a "Rojo", se marca solo este. En cambio, si le damos a cualquiera de las otras opciones, se queda todo marcado. Para que funcione, cada uno tiene que tener su propio "value".

Añado las líneas 15, 20, 25 y 30.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

opcion = IntVar()

#Radiobutton
Radiobutton(root,
           text="Rojo", 
           variable=opcion, 
           value=1).pack()

Radiobutton(root,
           text="Azul",
           variable=opcion, 
           value=2).pack()

Radiobutton(root,
           text="Verde",
           variable=opcion, 
           value=3).pack()

Radiobutton(root,
           text="Amarillo",
           variable=opcion, 
           value=4).pack()

#Bucle de ejecución
root.mainloop()

Ahora funciona perfecto. Lo que se almacenará cada vez en la variable de control "opcion", es el valor que tenemos marcado en cada momento. Aún no ocurre. Te explicaré por qué. Si pulso el "Rojo", se guardará un 1. Si pulso el "Verde" se guardará un 3. Mientras no pulse nada, se guarda un 0. Aunque de momento, debemos añadir una forma de actualizar y pasar estos valores a la variable de control.

Veamos primero como funcionan internamente estas variables de control.

Código interno de las variables de control

Si vamos al código interno a ver estas clases de las variables de control, veremos mejor como funcionan.

Class StringVar de Tkinter

Aquí tienes la clase de las variables de control StringVar().

Lo primero que vemos, es un valor por defecto. En el caso de las variables de string, nos deja un string vacío (línea 3). En su método get() podemos ver (aunque todavía no tienes que entender ese código) que obtiene un string y devuelve un string.

class StringVar(Variable):
    """Value holder for strings variables."""
    _default = ""

    def __init__(self, master=None, value=None, name=None):
        """Construct a string variable.

        MASTER can be given as master widget.
        VALUE is an optional value (defaults to "")
        NAME is an optional Tcl name (defaults to PY_VARnum).

        If NAME matches an existing variable and VALUE is omitted
        then the existing value is retained.
        """
        Variable.__init__(self, master, value, name)

    def get(self):
        """Return value of variable as string."""
        value = self._tk.globalgetvar(self._name)
        if isinstance(value, str):
            return value
        return str(value)

Class IntVar de Tkinter

Esta clase da a sus objetos un valor por defecto de 0 integer.

El método get() intenta obtener un valor de tipo int. Pero puede darse el caso de que se le pase un TypeError si le pasamos un valor decimal u otro tipo. En ese caso, intentará siempre hacer la conversión a int.

class IntVar(Variable):
    """Value holder for integer variables."""
    _default = 0

    def __init__(self, master=None, value=None, name=None):
        """Construct an integer variable.

        MASTER can be given as master widget.
        VALUE is an optional value (defaults to 0)
        NAME is an optional Tcl name (defaults to PY_VARnum).

        If NAME matches an existing variable and VALUE is omitted
        then the existing value is retained.
        """
        Variable.__init__(self, master, value, name)

    def get(self):
        """Return the value of the variable as an integer."""
        value = self._tk.globalgetvar(self._name)
        try:
            return self._tk.getint(value)
        except (TypeError, TclError):
            return int(self._tk.getdouble(value))

Class DoubleVar

Luego tenemos la Clase DoubleVar que por defecto lleva un valor de 0.0. Esta devuelve un número decimal.

class DoubleVar(Variable):
    """Value holder for float variables."""
    _default = 0.0

    def __init__(self, master=None, value=None, name=None):
        """Construct a float variable.

        MASTER can be given as master widget.
        VALUE is an optional value (defaults to 0.0)
        NAME is an optional Tcl name (defaults to PY_VARnum).

        If NAME matches an existing variable and VALUE is omitted
        then the existing value is retained.
        """
        Variable.__init__(self, master, value, name)

    def get(self):
        """Return the value of the variable as a float."""
        return self._tk.getdouble(self._tk.globalgetvar(self._name))

Class BooleanVar

Por último, la clase BooleanVar que intenta devolver un valor booleano. El valor por defecto es False.

class BooleanVar(Variable):
    """Value holder for boolean variables."""
    _default = False

    def __init__(self, master=None, value=None, name=None):
        """Construct a boolean variable.

        MASTER can be given as master widget.
        VALUE is an optional value (defaults to False)
        NAME is an optional Tcl name (defaults to PY_VARnum).

        If NAME matches an existing variable and VALUE is omitted
        then the existing value is retained.
        """
        Variable.__init__(self, master, value, name)

    def set(self, value):
        """Set the variable to VALUE."""
        return self._tk.globalsetvar(self._name, self._tk.getboolean(value))

    initialize = set

    def get(self):
        """Return the value of the variable as a bool."""
        try:
            return self._tk.getboolean(self._tk.globalgetvar(self._name))
        except TclError:
            raise ValueError("invalid literal for getboolean()")

Ver los valores de los Radiobutton en la variable de control.

Lo siguiente que voy a hacer, es ver los valores de cada Radiobutton en la variable de control.

Para que ver el valor que tiene la variable de control, lo puedes hacer con un Label o un print() de la siguiente forma:

Label(root, text=opcion.get()).pack()

Añade esta línea al final del código, antes del mainloop().

El valor que aparece pulsemos, la opción que pulsemos, es siempre 0. Para que este valor se actualice en esta etiqueta y ver lo que realmente se va enviando al programa, debemos obtener y enviar el "value" de la variable de control y generar una nueva etiqueta con cada valor.

Función para actualizar el valor de la variable de control

Lo siguiente que haremos, será una función que sea capaz de enviar y actualizar los valores en las etiquetas a medida que los seleccionamos y enviamos.

Fíjate en las líneas 11 a la 13 (función) y 36 a 39.

La función tiene una etiqueta que utiliza el parámetro "valor". Este parámetro, lo utilizo con una lambda en el botón. Lo que le paso por argumento, es el "value" del Radiobutton seleccionado en el momento de pulsar el botón (realmente el valor que lleva la variable de control).

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

opcion = IntVar()

# Función para el botón de envío
def actualiza_radio(valor):
    Label(root, text=valor).pack()

#RadioButton
Radiobutton(root,
           text="Rojo", 
           variable=opcion, 
           value=1).pack()

Radiobutton(root,
           text="Azul",
           variable=opcion, 
           value=2).pack()

Radiobutton(root,
           text="Verde",
           variable=opcion, 
           value=3).pack()

Radiobutton(root,
           text="Amarillo",
           variable=opcion, 
           value=4).pack()

# Botón de envío
boton_envia = Button(root,
           text="Enviar",
           command=lambda: actualiza_radio(opcion.get())).pack()

#Bucle de ejecución
root.mainloop()

Establecer valores por defecto en los Radiobutton

Por lo que has podido ver en el código de Tkinter, las IntVar tiene un valor establecido por defecto de 0. ¿Y si queremos que sea otro? Por ejemplo, que por defecto, tenga el valor 1 y que al iniciar el programa, que esté el color rojo seleccionado.

Hemos visto como obtener el valor de la variable de control con get() y ahora utilizaremos su método set() para establecer un valor.

Solo tienes que aplicar el método set() a la variable de control y darle un valor.

opcion = IntVar()
opcion.set(1)

Te dejo unos ejercicios resueltos para que practiques con todo esto.

3 comentarios en «0»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso Java Entrada anterior Los comentarios en Java
curso de Python Entrada siguiente Ejercicios de Python y Tkinter