Tutorial paso a paso para crear una calculadora científica con Python y Tkinter
Crear una calculadora científica utilizando Python y la biblioteca Tkinter es un excelente proyecto para desarrolladores principiantes e intermedios que quieren aprender sobre programación GUI Python, manejo de eventos y funciones matemáticas avanzadas. En este tutorial, te guiaré desde la configuración del entorno hasta la implementación completa, con bloques de código comentados y explicaciones detalladas para que puedas practicar y crear tu propia calculadora científica.
Índice
- Configuración del entorno
- Diseño de la interfaz gráfica con Tkinter
- Implementación de funciones matemáticas básicas y avanzadas
- Manejo de eventos y ejecución de operaciones
- Validación de entradas
- Conclusión y buenas prácticas de desarrollo en Python
Configuración del entorno
Para comenzar a desarrollar una aplicación GUI en Python con Tkinter, debes tener instalado Python en tu sistema.
Paso 1: Instalar Python
Si aún no tienes Python instalado, descarga la última versión desde python.org y sigue las instrucciones según tu sistema operativo.
Paso 2: Verificar la instalación de Tkinter
Tkinter viene incluido en la mayoría de las instalaciones estándar de Python. Para confirmar que funcione, abre una terminal o consola e ingresa:
1 2 |
python -m tkinter |
Si aparece una pequeña ventana titulada ‘Tk’, tienes Tkinter instalado correctamente. Si no, deberás instalarlo:
- En Linux (Ubuntu/Debian):
1 2 |
sudo apt-get install python3-tk |
- En Windows y macOS generalmente no es necesario instalarlo aparte.
Paso 3: Editor de código
Usa tu editor de código favorito. Recomendamos VSCode, PyCharm o incluso un editor simple como Sublime Text.
Diseño de la interfaz gráfica con Tkinter
Vamos a crear una ventana básica que contenga:
- Una pantalla para mostrar los números y resultados
- Botones para números, operaciones básicas (+, -, *, /)
- Botones para funciones científicas (sin, cos, tan, log, etc.)
Paso 1: Crear la ventana principal
1 2 3 4 5 6 7 8 9 10 11 12 |
import tkinter as tk from tkinter import ttk # Crear ventana root = tk.Tk() root.title("Calculadora Científica Python") root.geometry("480x600") # Tamaño de la ventana root.resizable(False, False) # Deshabilitar redimensionado # Ejecutar la ventana root.mainloop() |
Este código abrirá una ventana vacía titulada “Calculadora Científica Python”.
Paso 2: Añadir la pantalla
La pantalla será un Entry
de Tkinter configurado para mostrar resultados y entradas del usuario.
1 2 3 4 |
# Crear pantalla (Entry) para mostrar cálculo pantalla = ttk.Entry(root, font=("Arial", 24), justify="right") pantalla.grid(row=0, column=0, columnspan=6, sticky="nsew", padx=10, pady=10) |
Aquí usamos grid para organizar los widgets y una fuente grande para mejor visión.
Paso 3: Crear botones para números y operaciones
Para simplificar, agruparemos botones en listas y los añadiremos dinámicamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
botones_numeros = [ ('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('0', 4, 1), ('.', 4, 0) ] botones_operaciones = [ ('+', 1, 3), ('-', 2, 3), ('*', 3, 3), ('/', 4, 3), ('=', 4, 2), ('C', 4, 4) ] for (texto, fila, columna) in botones_numeros: boton = ttk.Button(root, text=texto, width=5) boton.grid(row=fila, column=columna, padx=5, pady=5) for (texto, fila, columna) in botones_operaciones: boton = ttk.Button(root, text=texto, width=5) boton.grid(row=fila, column=columna, padx=5, pady=5) |
Este código crea botones alineados en una cuadrícula.
Paso 4: Botones para funciones científicas
Agregaremos funciones como seno, coseno, tangente, logaritmo, exponente, raíz cuadrada.
1 2 3 4 5 6 7 8 9 10 11 |
funciones_cientificas = [ ('sin', 1, 4), ('cos', 1, 5), ('tan', 2, 4), ('log', 2, 5), ('exp', 3, 4), ('√', 3, 5) ] import math for (texto, fila, columna) in funciones_cientificas: boton = ttk.Button(root, text=texto, width=5) boton.grid(row=fila, column=columna, padx=5, pady=5) |
Ahora tienes una base para la interfaz de la calculadora científica.
Implementación de funciones matemáticas básicas y avanzadas
Vamos a implementar funcionalidades para las operaciones que hemos puesto en pantalla.
Paso 1: Variable para expresiones
Usaremos una variable para mantener la expresión actual que el usuario escribe.
1 2 3 4 5 6 7 8 9 |
expresion = "" # Función para actualizar pantalla def actualizar_pantalla(valor): global expresion expresion += str(valor) pantalla.delete(0, tk.END) pantalla.insert(tk.END, expresion) |
Paso 2: Función para calcular resultados
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Función para evaluar la expresión def calcular(): global expresion try: # Reemplazar caracteres para funciones matemáticas si se requiere resultado = eval(expresion) pantalla.delete(0, tk.END) pantalla.insert(tk.END, str(resultado)) expresion = str(resultado) # Guardamos para continuar calculando except Exception as e: pantalla.delete(0, tk.END) pantalla.insert(tk.END, "Error") expresion = "" |
Paso 3: Incorporar funciones científicas
Como eval
no reconoce sin
, cos
etc. directamente, podemos utilizar el módulo math
y definir un contexto seguro para evaluar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import math # Diccionario con funciones permitidas funciones_permitidas = {"sin": math.sin, "cos": math.cos, "tan": math.tan, "log": math.log10, "exp": math.exp, "sqrt": math.sqrt} import re def calcular(): global expresion try: # Reemplazar símbolos no válidos expr = expresion # Reemplazar raíz cuadrada para usar sqrt expr = expr.replace('√', 'sqrt') # Reemplazar coma decimal si existe expr = expr.replace(',', '.') # Buscar funciones y prepáralas para eval for func in funciones_permitidas.keys(): expr = re.sub(rf'{func}(?=[^a-zA-Z])', f'funciones_permitidas["{func}"]', expr) # Evaluar de forma segura resultado = eval(expr, {"__builtins__": None}, funciones_permitidas) pantalla.delete(0, tk.END) pantalla.insert(tk.END, str(resultado)) expresion = str(resultado) except Exception: pantalla.delete(0, tk.END) pantalla.insert(tk.END, "Error") expresion = "" |
Paso 4: Función para limpiar la pantalla
1 2 3 4 5 |
def limpiar(): global expresion expresion = "" pantalla.delete(0, tk.END) |
Manejo de eventos y ejecución de operaciones
Ahora conectaremos los botones con las funciones que hemos creado.
Paso 1: Asignar comandos a botones numéricos y básicos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
for (texto, fila, columna) in botones_numeros: boton = ttk.Button(root, text=texto, width=5, command=lambda t=texto: actualizar_pantalla(t)) boton.grid(row=fila, column=columna, padx=5, pady=5) for (texto, fila, columna) in botones_operaciones: if texto == '=': boton = ttk.Button(root, text=texto, width=5, command=calcular) elif texto == 'C': boton = ttk.Button(root, text=texto, width=5, command=limpiar) else: boton = ttk.Button(root, text=texto, width=5, command=lambda t=texto: actualizar_pantalla(t)) boton.grid(row=fila, column=columna, padx=5, pady=5) |
Paso 2: Asignar comandos a botones científicos
1 2 3 4 5 6 7 8 9 |
# Estos botones agregan la función y un paréntesis para facilitar uso for (texto, fila, columna) in funciones_cientificas: if texto == '√': operacion = '√(' else: operacion = texto + '(' boton = ttk.Button(root, text=texto, width=5, command=lambda op=operacion: actualizar_pantalla(op)) boton.grid(row=fila, column=columna, padx=5, pady=5) |
Paso 3: Ejecutar la aplicación completa
Para probar todo junto, coloca este bloque al final de tu código:
1 2 3 |
if __name__ == '__main__': root.mainloop() |
Validación de entradas
Para mejorar la experiencia y evitar errores:
- La pantalla debe aceptar solo entradas válidas.
- Se puede limitar el uso de caracteres no permitidos.
- Se maneja el error en el cálculo mostrando “Error”.
Puedes reforzar esto con una función que valide la entrada pulsada, pero para principiantes, manejar errores en la función calcular()
es un buen inicio.
Código completo resumido
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
import tkinter as tk from tkinter import ttk import math import re # Variables globales global expresion expresion = "" # Funciones permitidas para cálculos avanzados funciones_permitidas = { "sin": math.sin, "cos": math.cos, "tan": math.tan, "log": math.log10, "exp": math.exp, "sqrt": math.sqrt } def actualizar_pantalla(valor): global expresion expresion += str(valor) pantalla.delete(0, tk.END) pantalla.insert(tk.END, expresion) def limpiar(): global expresion expresion = "" pantalla.delete(0, tk.END) def calcular(): global expresion try: expr = expresion expr = expr.replace('√', 'sqrt') expr = expr.replace(',', '.') # Sustituir funciones con el acceso al dict for func in funciones_permitidas.keys(): expr = re.sub(rf'{func}(?=[^a-zA-Z])', f'funciones_permitidas["{func}"]', expr) resultado = eval(expr, {"__builtins__": None}, funciones_permitidas) pantalla.delete(0, tk.END) pantalla.insert(tk.END, str(resultado)) expresion = str(resultado) except: pantalla.delete(0, tk.END) pantalla.insert(tk.END, "Error") expresion = "" # Crear ventana global root root = tk.Tk() root.title("Calculadora Científica Python") root.geometry("480x600") root.resizable(False, False) pantalla = ttk.Entry(root, font=("Arial", 24), justify="right") pantalla.grid(row=0, column=0, columnspan=6, sticky="nsew", padx=10, pady=10) # Botones botones_numeros = [ ('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('0', 4, 1), ('.', 4, 0) ] botones_operaciones = [ ('+', 1, 3), ('-', 2, 3), ('*', 3, 3), ('/', 4, 3), ('=', 4, 2), ('C', 4, 4) ] funciones_cientificas = [ ('sin', 1, 4), ('cos', 1, 5), ('tan', 2, 4), ('log', 2, 5), ('exp', 3, 4), ('√', 3, 5) ] # Asignar botones numéricos for (texto, fila, columna) in botones_numeros: boton = ttk.Button(root, text=texto, width=5, command=lambda t=texto: actualizar_pantalla(t)) boton.grid(row=fila, column=columna, padx=5, pady=5) # Asignar botones operaciones for (texto, fila, columna) in botones_operaciones: if texto == '=': boton = ttk.Button(root, text=texto, width=5, command=calcular) elif texto == 'C': boton = ttk.Button(root, text=texto, width=5, command=limpiar) else: boton = ttk.Button(root, text=texto, width=5, command=lambda t=texto: actualizar_pantalla(t)) boton.grid(row=fila, column=columna, padx=5, pady=5) # Botones científicos for (texto, fila, columna) in funciones_cientificas: if texto == '√': operacion = '√(' else: operacion = texto + '(' boton = ttk.Button(root, text=texto, width=5, command=lambda op=operacion: actualizar_pantalla(op)) boton.grid(row=fila, column=columna, padx=5, pady=5) if __name__ == '__main__': root.mainloop() |
Conclusión y buenas prácticas de desarrollo en Python
¡Felicidades! Ahora tienes una calculadora científica básica funcional desarrollada en Python usando Tkinter. Este proyecto demuestra el poder de la programación GUI Python y cómo implementar funciones matemáticas avanzadas con validación y manejo de eventos.
Buenas prácticas para seguir aprendiendo:
- Modulariza el código en funciones y/o clases para facilitar mantenimiento.
- Añade más funciones científicas como factorial, potencia, etc.
- Mejora la interfaz con estilos (usando
ttk.Style
). - Añade validaciones más robustas para evitar errores.
- Experimenta con otros frameworks GUI como PyQt o Kivy para expandir conocimientos.
La práctica constante mejora tus habilidades, te invito a modificar este código y adaptarlo a tus necesidades.
Si este tutorial te ha gustado, ¡compártelo con otros programadores y no dudes en dejar tus preguntas o sugerencias!