Calculadora con interfaz gráfica en Python (2ª Parte)
Hola, mi nombre es Antonio Alfonso Martínez y en el presente artículo me dispongo a continuar con la guía para aprender cómo crear una calculadora en Python con interfaz gráfica. En el artículo anterior , Calculadora con interfaz gráfica en Python (1ª Parte) , veíamos como creábamos los elementos gráficos de nuestra calculadora (la pantalla y los botones). Una vez completado todo el proceso, obteníamos el siguiente resultado: Sin embargo, nuestra calculadora tenía el inconveniente de que no era capaz de realizar ninguna operación. Así en el presente artículo nos encargaremos de hacer que el programa realice los cálculos que le pidamos mediante la introducción de la correspondiente información, por medio de los botones. Para empezar, diremos que vamos a crear un sistema de funciones (en el que unas se llaman a otras) que “conecte” los botones (concretamente la información que introduzcamos haciendo “clic” en ellos) con la función “eval” (para la realización de operaciones aritméticas con cadenas) y con la función que creemos para la visualización del resultado.
Debido a que vamos a usar los botones para introducir las operaciones a realizar, crearemos una función (a la que llamaremos “btnClik”) la cual actuará cada vez que hagamos “clic” en algunos de los botones y cuya función será la de ir acumulando (mediante “global” y la variable “operador”) los números y operadores implicados en la operación que queremos realizar.
A su vez la función tomará como argumento la variable “num”, que no es otra cosa que el carácter que representa cada uno de los botones (a excepción de los botones “BotonC” y “BotonResul”, como tendremos ocasión de ver en su momento):
Sin embargo, para “conectar” esta función con cada uno de los botones, tendremos que incluir en el código de cada uno de ellos, una llamada a la función “btnClick”, lo cual haremos del siguiente modo:
Como se puede apreciar, introducimos una nueva función (llamada “command”) mediante la cual estamos indicándole al programa, que función es la que queremos que se aplique al hacer “clic” en el botón. A su vez, para el caso de los botones que contengan una llamada a “btnClik”, incluiremos el carácter (un número o un operador) que queremos que la función llamada (“btnClik”) tome como argumento (variable “num”), entre paréntesis.
Finalmente (y siguiendo con la función “btnClik”) nuestra función representará en la pantalla, la operación a realizar mediante “input_text.set()” tomando como argumento entre paréntesis la cadena de caracteres que representa la operación (la cual se habrá almacenado en la variable “operador”).
Antes de seguir con la siguiente función, hay que recordar que tanto la variable destinada a contener la cadena que representa la operación a realizar (variable “operador”) así como la variable que empleamos para visualizar dicha cadena en la pantalla, tienen que ser previamente declaradas (lo cual hemos hecho justo antes de la creación de los botones, como se ve en la imagen): De ese modo, puesto que “operador” contendrá los elementos que introduzcamos mediante los botones, (haciendo uso de una función “lambda”), esta será una variable inicialmente nula (“operador=(“”)”).
En elcaso de la variable “input_text” (lo que se visualizará en la pantalla) especificaremos que será una variable en formato cadena (“input_text=StringVar()”) y a su vez deberemos incluirla dentro de la variable “Salida” (que hemos declarado después de los botones).
La llamada mediante “command” a la función “btnClik”, la llevaremos a cabo para todos los botones a excepción de “BotonC” y “BotonResul” los cuales llamaran a otras funciones de las que hablaremos a continuación.
Una vez que con la función “btnClick” hemos creado (y visualizado) la cadena de caracteres que componen la operación a realizar, el siguiente paso será el crear una función (a la que llamaremos “operacion”) que, mediante la función “eval” (destinada al calculo con cadenas) realice las operaciones establecidas con la función anterior, mediante la creación de la variable “opera”:
En la función “operacion” tomamos la cadena “operador”, la cual calcularemos, mediante “eval” para almacenar el resultado en la variable “opera”,finalmente (al igual que hacíamos en la función “btnClick”) usaremos “input_text” para (en este caso) visualizar el resultado almacenado en “opera”. Pero para que esta función se aplique, tendremos que asociarla con uno de los botones (concretamente con le botón correspondiente al signo “=”) dicho botón es el llamado “BotonResul” (el último que hemos creado) en el que haremos la llamada a la función “operacion”, escribiendo “command=operacion”.
La creación de estas dos variables ya nos va a permitir el visualizar la operación a realizar y el resultado de la misma, como se muestra en este ejemplo:
No obstante, es posible que, después de una operación, queramos efectuar otra operación distinta. Esto no es posible todavía, de modo que para realizar una operación nueva, tendríamos que cerrar la calculadora e iniciarla de nuevo. Por ello vamos a crear una nueva función (a la que hemos dado el nombre de “clear”) que una vez introducido una cadena (variable “operador”) o visualizado un resultado (variable “opera”) nos permita, haciendo “clic” en el botón “C”, limpiar la pantalla y dejar el programa listo para efectuar una nueva operación sin necesidad de reiniciarlo. La referida función “clear” es bastante sencilla y es la que sigue:
Así tenemos una función que toma la cadena de caracteres “operador” (recopilada mediante “global”) y la devuelve a su estado original nulo (“operador=(“”)”). Una vez que “operador” vuelve a no tener ningún valor, la representaremos en la pantalla (mediante “input_text.set(operador)”) quedando la pantalla (y el programa) lista para la introducción de nuevas operaciones.
Como hemos dicho que esta función se ejecutará cuando hagamos “clic” en el botón “C”, tendremos que incluir la correspondiente llamada a dicha función (mediante “command=clear”) en el botón correspondiente a “C”, el cual es el denominado “BotonC” de nuestra lista de botones.
Y con esto nuestra calculadora estaría lista para funcionar. Sin embargo aún nos queda un pequeño detalle: Imaginemos que nuestro usuario intenta efectuar una operación como la siguiente:
Y, después de haber introducido dicha operación, nuestro usuario hace “clic” en el botón “=” para ver el resultado:
Como se puede ver en el “shell” de nuestra calculadora, la introducción de una operación no válida (en este caso, la división por 0) ha llevado a que nuestro programa falle, interrumpiéndose el correcto funcionamiento del mismo. Esto se ha debido a una doble causa: Por un lado, le hemos pedido al programa que efectúe una operación imposible (en este caso ha sido la división por 0, aunque este mismo problema se nos podría presentar si, por ejemplo, introdujésemos una secuencia de caracteres desordenada, con la que la función “eval” no pudiese trabajar). La otra causa es que, ante este tipo de eventualidades, no hemos dotado al programa (en este caso, a nuestra calculadora) de una respuesta que impida la interrupción de su correcto funcionamiento (en pocas palabras: No le hemos indicado a la calculadora, que ha de hacer en estos casos).
Como sabemos, en las calculadoras, que normalmente usamos, cuando se introduce una operación prohibida o imposible, la calculadora muestra en pantalla un mensaje de error. Pues eso mismo es lo que vamos a hacer nosotros con nuestra calculadora.
Para ello, vamos a tener que volver a la función “operacion” (que como recordaremos, era la encargada de realizar el cálculo de nuestra operación, mediante “eval”, a partir de la cadena creada con la función “btnClik”) e introducir unas pequeñas modificaciones:
El cambio ha consistido en introducir una sentencia “try” mediante la cual le estamos diciendo a la función que “intente”, mediante “eval”, llevar a cabo la operación aritmética introducida (la cual viene dada por la variable “operador”). De modo que si el programa consigue realizarla (por tratarse de una operación válida) con éxito, visualizará el resultado (variable “opera”) mediante “input_text.set(opera)). Sin embarga, en el caso de que la operación no se pueda llevar a cabo (por ser una operación no válida, o por tener sus caracteres desordenados), se producirá una excepción (mediante “except”) que, en primer lugar, aplicará la función “clear” (que creamos en su momento) de modo que la variable “operador” volverá a su estado original (es decir, operador=””) y en segundo lugar, la variable “opera” (la cual estaba destinada a ser el resultado de la operación), pasará a ser igual a la palabra “ERROR”, que sería lo que finalmente se mostraría en la pantalla, mediante “input_text.set”.
Para comprobar que, efectivamente, nuestra modificación realmente funciona, introduciremos la misma operación prohibida de antes:
Y también como antes, haremos “clic” en el botón “=” para que la calculadora muestre el resultado:
Ahora no se interrumpe el correcto funcionamiento de nuestra calculadora, sino que, simplemente muestra el mensaje “ERROR” en la pantalla (indicándonos así que la operación introducida no es válida) y permitiéndonos, a su vez, la posibilidad de introducir directamente, una nueva operación sin necesidad de volver a reiniciar el programa.
Y con esto ya tenemos creada nuestra calculadora con interfaz gráfica en Python, para hacer las operaciones que le indiquemos mediante sus botones.
En el presente artículo hago mención, en repetidas ocasiones, de la función “eval” (para la realización de cálculos con cadenas). En el siguiente enlace hablo un poco más de dicha función:
https://wordpress.com/post/programacionpython80889555.wordpress.com/408
A su vez, podéis ver el código completo de la calculadora en el siguiente enlace a “Github”:
https://github.com/antonioam82/Calcu/blob/master/CALCULADORA%202.py
Si quieres formar parte de la comunidad KeepCoding, compartiendo información relevante sobre desarrollo Web, Mobile, Big Data o Blockchain puedes escribirnos a [email protected] .
Programador y desarrollador autodidacta. Semanalmente publica en el blog “El programador Chapuzas“ (wordpress) y también colaboro en las páginas “Código Comentado” y “Algoritmos MathPy” de Facebook.