miércoles, 27 de abril de 2022

¿Cómo funcionan las variables de control en Tkinter y en Guizero?

imagen de entrada del post

Variables de control en Tkinter y Guizero.

Para ver el tema de las variables de control vamos a ver como se tratan primero en Tkinter y luego en Guizero.

Empecemos con Tkinter.

Las variables de control son unos objetos especiales que se asocian a los widgets para almacenar los valores que estos puedan tomar y poder así luego usarlos en otras partes del programa. Estos valores pueden ser numéricos, texto u opciones Boolenas.

Lo bueno de esto es que cuando una variable de control cambia de valor, esto queda automáticamente reflejado en el widget que lo utiliza o también puede ocurrir al revés. 

Estas variables también se utilizan para conectar varios widgets del mismo tipo, por ejemplo varios controles del tipo RadioButton (en este caso tomarán uno de los varios posibles.)

¿Cómo declaramos estas variables de control?

Las declaración de las variables de control va a estar en función del tipo de dato que almacenan. 

entero = IntVar() -> Para números enteros
flotante = DoubleVar() -> Para número reales.
cadena = StringVar() -> Para cadenas.
booleano = BooleanVar() -> Para datos de tipo Booleano.

Además en el momento de declararlas también podemos establecer un valor inicial, con el argumento "value". Por ejemplo:

numero_pizzas = IntVar(value=1) -> Para números enteros


Para establecer, leer o detectar cambios en las variables de control utilizamos los siguientes métodos.

Método set()

Asigna un valor a una variable de control. Se utiliza para modificar el valor o estado de un widget.

Por ejemplo:

uso de variables de control en Tkinter


from tkinter import *
import tkinter.ttk as ttk
raiz = Tk()
nombre = StringVar()
numero = DoubleVar()
nombre.set("El número pi es: ")
numero.set(3.1416)
# Dibuja cuadro de entrada de texto con el texto 
blog = ttk.Entry(raiz, textvariable=nombre, width=25)
blog.pack()
# Dibuja una etiqueta con el numero pi
arti = ttk.Label(raiz, textvariable=numero)
arti.pack()
raiz.mainloop()

Método get()

El método get() nos facilita el valor que tenga en un momento dado una variable de control.  Si te fijas en el ejemplo anterior creamos dos variables de control "nombre" y "número". Si quisiésemos saber el valor de ambas utilizaríamos 

print(f"Texto cuadro = '{nombre.get()}'")
print(f"Cuadro númerico = {numero.get()}")

lo que tendría una salida similar a esta:

Texto cuadro= 'El número pi es: '
Cuadro númerico = 3.1416


método trace()

Este método se utiliza para detectar cambios en el valor de una variable. Podemos detectar cuando es leída, cambia de valor o es borrada.

Su estructura es:

variable.trace(suceso, función)

En donde suceso puede tomar alguno de los siguientes valores:

"r" - Lectura de la variable

"w" - Escritura de la variable

"u" - Borrado de la variable.

El segundo elemento hace referencia a que función se ejecutará cuando se desate el suceso.

Para verlo con un ejemplo vamos a usar un Entry con un texto inicial y verás como si borras o escribes en el estas modificando la variable y así se mostrará en el terminal.

from tkinter import *
import tkinter.ttk as ttk
raiz = Tk()


def cambia(*args):
    print("Ha cambiado su valor")

variable = StringVar()
variable.set("texto de Prueba")
entrada = ttk.Entry(raiz, textvariable=variable, width=25)
entrada.pack()

variable.trace("w", cambia)


raiz.mainloop()


método trace



Estrategias de control de cambios en la aplicación: validación posterior o inmediata.

Cuando construimos una aplicación con varios widgets podemos usar dos estrategias para controlar los datos que se introducen en la ejecución de un programa.

- Introducir primero todos los datos y posteriormente realizar las operaciones, presionando por ejemplo un botón.

- Haciendo uso del método trace() y/o de la opción 'command' para calcular y validar la información justo en el momento en el que un widget y su variable asociada cambien de valor. 

Vamos a practicar estos conceptos con un caso práctico en el que veremos ambas opciones.

Supongamos un programa que calcule el precio de un billete de autobús, teniendo en cuenta el número de pasajeros, el tipo de billete (solo ida o ida y vuelta), la clase en la que se viaja (normal, supra o gran lujo), la distancia entre el lugar y el destino en Kilómetros y el precio por kilometro (0,20 € / Km)

El precio total se calcula como el numero de pasajeros por km y precio por Kilometro pero teniendo en cuenta que:

- si el billete es solo de ida se multiplica el total por 1.5

- si la clase del asiento es supra se multiplica por 1,2 y si es gran lujo se multiplica por 2.

Primera opción. Introducción de los datos y validación posterior.

El calculo del importe a pagar se realizará después de pulsar el botón "Calcular"

ejemplo de validación posterior


Puedes encontrar el código de la aplicación en el siguiente enlace.

Segunda Opción. Introducción de datos y calculo inmediato.

En este caso no hay un botón "Calcular" ya que el calculo se hace instantáneamente cada vez que modificamos algún dato. Para los widgets de entradas de datos 'entry()' se definen dos "trace" para detectar cualquier cambio en los datos. En el resto de widgets se utiliza la opción "command".

ejemplo calculo inmediato


Puede encontrar el detalle del código en el enlace.

Con Guizero.

Primera opción. Introducción de los datos y validación posterior.

Al igual que anteriormente realizamos primero todo el diseño de la ventana y los widgets. En guizero para asignar un valor o texto al widget usamos la propiedad value del mismo. Así si creamos por ejemplo un cuadro de texto y lo llamamos Caja, podemos poner el texto dentro se la siguiente forma:

Caja.value = "El texto que queramos poner"

y si lo que queremos es ver el valor que ya esta escrito en un widget tenemos que leer esta propiedad del widget. Por ejemplo si queremos guardar en una variable algo que ya esta escrito en una caja de texto podemos usar:

variable = Caja.value

ejemplo con guizero


Puedes encontrar el código completo en Guizero en el enlace.

Segunda Opción. Actualización automática del resultado al introducir los datos.

ejemplo con guizero

Aquí la estrategia es un poco distinta, pero muy sencilla. Cada vez que modificamos uno de los widgets que admiten variación de datos, en el propio elemento se utiliza el parámetro command para ejecutar la función que calcula el resultado.

Pej:

idavu = CheckBox(box, text='Ida y vuelta', grid=[0,2], align='left', command=calculo)

o

Text(box, text="Distancia en Km.", grid=[0,5], align="left")

dist = TextBox(box, grid=[0,6], width=20, command=calculo)

dist.value = 1

Puedes verlo en más detalle en el código del programa en el siguiente enlace.



No hay comentarios:

Publicar un comentario