TkInter. Botón de comando
Para disponer de un mínimo de elementos que nos permitan crear una GUI funcional, a lo ya aprendido le falta algo indispensable: un botón, recurso necesario para manejar comandos. Lo "malo" es que implementarlo nos obliga a entrar en contenidos (mejor, enlazar con) que superan, con mucho, las pretensiones de esta incursión por el mundo de la GUI. Qué remedio.
Además de estos condicionantes, explicar cómo implementar un botón conlleva hacer un primer acercamiento a alguna utilidad, puesto que no tiene mucho sentido no asociar el botón a una función que realice una acción y, por ello, que esa acción implique algún tipo de utilidad, por mínima que ésta sea.
Tampoco hay que preocuparse demasiado por estas cuestiones: se hacen y en paz, pero con una advertencia: con esta entrada no iniciamos la segunda fase de este proceso; dar utilidad a la acción de la función sólo tiene, por ahora, una funcionalidad pedagógica (aprender a manejar botones)
Aun así, como hay que hacerla, hay que explicarla para que se entienda mejor el "proyecto": vamos a crear una calculadora de sumas muy sencillita. Contendrá cuatro etiquetas, dos entradas y dos botones de comando. Obviamente requiere la creación de dos funciones y el uso de una variable.
Como en otros casos, me voy a detener en explicar únicamente la implementación de lo que resulta novedoso, quedando el resto disponible en el script. Incluyo en el concepto "novedad" lo que no debería serlo: la creación de una función sencilla, aunque remito a las entradas ya publicadas con anterioridad que hablan de las funciones.
No obstante, no se entendería el código si no se presenta en su conjunto, así que habrás de hacer un ejercicio de repaso para entender lo que ya se explicó en entradas anteriores.
Para comprenderlo mejor, te puede ayudar esta breve descripción de las partes del código, que, por otro lado, quedan explicadas también en los comentarios del algoritmo:
Fases:
- Creamos las funciones necesarias: (Suma() y Cerrar()
- Creamos la ventana
- Implementamos etiqueta descriptiva
- Implementamos los dos juegos de etiqueta+entrada con función de input
- Introducimos el primer botón de comando (función Sumar())
- Y a continuación la etiqueta en la que escribir el resultado de la suma
- Para finalizar con un botón de cierre de la ventana, asociado a la función Cerrar()
Recuerda que las funciones se escriben al inicio del script para que estén disponibles cuando sean llamadas desde los botones. Además, estas funciones requieren también del uso de al menos una variable: la necesaria para asociar el resultado al contenido (lo escrito) en la etiqueta ubicada después del primer botón.
Puedes acceder a un visionado más cómodo de la imagen haciendo clic en ella y regresar a la entrada pulsado la tecla escape o cerrando la ventana desde el icono (X) situado en la esquina superior derecha.
En esta captura de pantalla, en la que hemos quitado los comentarios para facilitar el manejo de la imagen, puedes observar la posición que ocupan las dos funciones (líneas 2 a 6) y la que ocupa la variable sResultado (línea 11) que sirve para contener el resultado de la operación, tal y como se calcula en la primera función (Sumar()).
Respecto a la función Sumar():
- A la variable interna suma se asigna el resultado de la operación en la que sumamos los dos contenidos de las dos entradas:
int(sSuma1.get())+int(sSuma2.get())
Observa que primero convertimos a integer [int(sSuma1.get())] mediante la función int(), los valores capturados de las entradas. Esto es necesario porque las Entry devuelven valores string, no integer.
Observa también que lo que hacemos es utilizar el método get() (sSuma1.get()) como forma de acceder al contenido de las entradas.
- Esa misma variable suma es la que sirve para retornar el resultado de la operación, asociado a la variable creada a tal fin [return sResultado.set(suma)], utilizando el método set() (el opuesto a get())
La posición que ocupa la variable sResultado (línea 11) y la forma en que se declara [sResultado=tk.StringVar()] son importantes, igual que la forma en que se asocia a la etiqueta en la que se expone (línea 24) [textvariable=sResultado y no text=sResultado, como sería de esperar]
No estoy aun en condiciones de poder explicar todo esto, pero sí de aportar algunos datos, incluyendo lo obvio: poner la variable en otra posición o cambiar las formulaciones produce errores.
Posiblemente la posición en que se ubica la variable permita atribuirle el contenido resultante de la ejecución de la función: si la variable se coloca antes que la función y antes de la creación de la ventana, se produce error.
La variable debe ser declarada como variable tipo string mediante el método tk específico [tk.StringVar()], declararla simplemente como variable no permite obtener el resultado deseado, ni de la función ni de ubicación en la etiqueta correspondiente.
Finalmente, la fórmula textvariable=sResultado permite identificar que el contenido de esta etiqueta va a ser una variable y no texto literal, pero no alcanzo a entender por qué en este caso la fórmula de asignación del contenido de una variable no funciona y en otras ocasiones sí.
De hecho si incluyo la variable string etq1Texto y le doy un contenido,
etq1Texto = "Primer sumando"
y después la uso en sustitución del texto a introducir directamente en la segunda etiqueta...
etqSum1 = tk.Label(ventana,text=etq1Texto,bg="red",fg="white")
... el resultado es positivo. Esto parece indicar que la restricción observada (que no se produce en este ejemplo) está asociada al uso de la variable sResultado dentro de la función Sumar(), posiblemente por que no se trata de una variable, sino de un objeto que hereda métodos de la clase tKinter (tk.StringVar()), en concreto, el método set()
La función Cerrar() asociada al segundo botón de comando (btnCerrar), es meramente un adelanto de la funcionalidad que se le puede dar a una GUI TkInter. Interesa entender qué hace el método destroye(), perteneciente al objeto ventana, que es a su vez un objeto hijo que hereda del objeto padre que podemos identificar (intuitivamente) con TkInter. Todo esto nos acerca al paradigma POO, pero no es necesario ir más allá... por ahora.
Para finalizar: aunque la imagen anterior contiene todo el código de este script, creo que es mejor que puedas acceder al original que sí contiene los comentarios necesarios para leer su contenido con más facilidad. Aquí te dejo el enlace.