Interfaces gráficas III
Desarrollo de una simple calculadora
En este apartado vamos a usar lo explicado hasta los momentos del uso de la libreria TKINTER para desarrollar una calculadora similar a la del sistema de Windows. Para ello vamos directamente al código y explicaremos alguno que otro aspecto:
from tkinter import *
import os
#Funciones
def Pulsacion(sValor):
global sOperacion
global bNuevoMonto
if bNuevoMonto:
sNumeroPantalla.set(0)
if bNuevoMonto and sNumeroPantalla.get() != '0' or bNuevoMonto and sNumeroPantalla.get() == '0' and sValor != '0' or not bNuevoMonto:
if sNumeroPantalla.get() != '0':
sNumeroPantalla.set(sNumeroPantalla.get()+sValor)
else:
sNumeroPantalla.set(sValor)
bNuevoMonto=False
def Suma(sValorPantalla):
global bNuevoMonto
global sOperacion
global subTotal
if not bNuevoMonto:
if sOperacion=='Suma' or sOperacion =='':
subTotal+=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Resta':
subTotal-=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Multiplica':
subTotal*=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion =='Divide':
subTotal/=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
sOperacion='Suma'
bNuevoMonto=True
def Resta(sValorPantalla):
global sOperacion
global subTotal
global bNuevoMonto
if not bNuevoMonto:
if sOperacion=='Suma':
subTotal+=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Resta' or sOperacion =='':
subTotal-=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Multiplica':
subTotal*=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion =='Divide':
subTotal/=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
sOperacion='Resta'
bNuevoMonto=True
def Multiplica(sValorPantalla):
global sOperacion
global subTotal
global bNuevoMonto
global bNuevaOperacion
if not bNuevoMonto:
if bNuevaOperacion and subTotal==0:
subTotal=1
if sOperacion=='Suma':
subTotal+=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Resta':
subTotal-=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Multiplica' or sOperacion =='':
subTotal*=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion =='Divide':
subTotal/=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
sOperacion='Multiplica'
bNuevoMonto=True
bNuevaOperacion=False
def Divide(sValorPantalla):
global sOperacion
global subTotal
global bNuevoMonto
global bNuevaOperacion
if not bNuevoMonto:
if bNuevaOperacion and subTotal==0:
subTotal=int(sValorPantalla)*int(sValorPantalla)
if sOperacion=='Suma':
subTotal+=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Resta':
subTotal-=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion=='Multiplica':
subTotal*=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
elif sOperacion =='Divide' or sOperacion == '':
subTotal/=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
sOperacion='Divide'
bNuevoMonto=True
bNuevaOperacion=False
def Resultado(sValorPantalla):
global subTotal
global sOperacion
if sOperacion == 'Suma' and not bNuevoMonto:
subTotal +=int(sValorPantalla)
elif sOperacion == 'Resta' and not bNuevoMonto:
subTotal-=int(sValorPantalla)
elif sOperacion == 'Multiplica' and not bNuevoMonto:
subTotal*=int(sValorPantalla)
elif sOperacion == 'Divide' and not bNuevoMonto:
subTotal/=int(sValorPantalla)
sNumeroPantalla.set(subTotal)
subTotal=0
sOperacion='Resultado'
def LimpiarTodo():
global subTotal
global sOperacion
global bNuevoMonto
global bNuevaOperacion
subTotal=0
sNumeroPantalla.set(0)
bNuevoMonto=True
bNuevaOperacion=True
sOperacion=''
os.system('cls')
#Inicialización de variables globales
sOperacion = ''
subTotal=0
bNuevoMonto=True
bNuevaOperacion=True
#Ventana principal
winPrincipal=Tk()
winPrincipal.title('*** Calculadora ***')
frmPrincipal=Frame(winPrincipal)
frmPrincipal.pack()
#Pantala de datos
sNumeroPantalla=StringVar()
tbPantalla=Entry(frmPrincipal,textvariable=sNumeroPantalla)
tbPantalla.grid(row=0,column=0,padx=0,pady=2,columnspan=4)
tbPantalla.config(bg='black',fg='#3FF400',justify='right')
#Fila 1
btBoton7=Button(frmPrincipal, text='7',width=3,command=lambda:Pulsacion('7'))
btBoton8=Button(frmPrincipal, text='8',width=3,command=lambda:Pulsacion('8'))
btBoton9=Button(frmPrincipal, text='9',width=3,command=lambda:Pulsacion('9'))
btDivide=Button(frmPrincipal,text='/',width=3,command=lambda:Divide(tbPantalla.get()))
btBoton7.grid(row=1,column=0,padx=2,pady=3)
btBoton8.grid(row=1,column=1,padx=2,pady=3)
btBoton9.grid(row=1,column=2,padx=2,pady=3)
btDivide.grid(row=1,column=3,padx=2,pady=3)
#Fila 2
btBoton4=Button(frmPrincipal, text='4',width=3,command=lambda:Pulsacion('4'))
btBoton5=Button(frmPrincipal, text='5',width=3,command=lambda:Pulsacion('5'))
btBoton6=Button(frmPrincipal, text='6',width=3,command=lambda:Pulsacion('6'))
btDivide=Button(frmPrincipal,text='*',width=3,command=lambda:Multiplica(tbPantalla.get()))
btBoton4.grid(row=2,column=0,padx=2,pady=3)
btBoton5.grid(row=2,column=1,padx=2,pady=3)
btBoton6.grid(row=2,column=2,padx=2,pady=3)
btDivide.grid(row=2,column=3,padx=2,pady=3)
#Fila 3
btBoton1=Button(frmPrincipal, text='1',width=3,command=lambda:Pulsacion('1'))
btBoton2=Button(frmPrincipal, text='2',width=3,command=lambda:Pulsacion('2'))
btBoton3=Button(frmPrincipal, text='3',width=3,command=lambda:Pulsacion('3'))
btResta=Button(frmPrincipal,text='-',width=3,command=lambda:Resta(tbPantalla.get()))
btBoton1.grid(row=3,column=0,padx=2,pady=3)
btBoton2.grid(row=3,column=1,padx=2,pady=3)
btBoton3.grid(row=3,column=2,padx=2,pady=3)
btResta.grid(row=3,column=3,padx=2,pady=3)
#Fila 4
btBoton0=Button(frmPrincipal, text='0',width=3,command=lambda:Pulsacion('0'))
btBotonDecimal=Button(frmPrincipal, text='.',width=3,command=lambda:Pulsacion('.'))
btBotonIgual=Button(frmPrincipal,text='=',width=3,command=lambda:Resultado(tbPantalla.get()))
btBotonSuma=Button(frmPrincipal, text='+',width=3,command=lambda:Suma(tbPantalla.get()))
btBoton0.grid(row=4,column=0,padx=0,pady=3)
btBotonDecimal.grid(row=4,column=1,padx=2,pady=3)
btBotonIgual.grid(row=4,column=2,padx=2,pady=3)
btBotonSuma.grid(row=4,column=3,padx=2,pady=3)
#Fila 5
btBotonimpiarTodo=Button(frmPrincipal,text='Limpiar todo',width=18,command=lambda:LimpiarTodo())
btBotonimpiarTodo.grid(row=5,column=0,padx=0,pady=3,columnspan=4)
sNumeroPantalla.set('0')
LimpiarTodo()
winPrincipal.mainloop()
Resultado del ingreso de la secuencia 3+2*2+10-5+15/5=:
Como podemos ver, a pesar que aún faltan mejoras para que se asemeje a la funcionalidad básica de la calculadora de Windows, ya podemos realizar las 4 operaciones básicas de suma, resta, multiplicación y división. No está implementado en este código el uso del decimal ni el ingreso de los mismos, ya que no es el objetivo de este apartado entrar de lleno en programación de la funcionalidad de la calculadora, sino mas bien el diseño de la interfaz y el llamado a funciones desde los botones, asó como la interacción con los widgets de la raíz, cosa que quedó mostrada en el ejemplo anterior.
Es destacable en este código el uso de las funciones lambda y el uso de variables booleanas para determinar el comportamiento del botón pulsado ya que los botones de operación suma, resta, muiltiplicación y división, deben ejecutar la operación anterior a ellos en caso de existir alguna e ir acumulando en una variable para que el próximo botón recuerde el monto y ejecute la operación anterior y vaya mostrando el resultado por pantalla.

Comentarios
Publicar un comentario