Curso-lenguaje-python/dia_12/mi_restaurante.py
2023-04-19 07:23:56 +02:00

1066 lines
25 KiB
Python

"""
Programa día 12 - Aplicación de facturación - Mi restaurant
tkinter
"""
from tkinter import *
import random
import datetime
from tkinter import filedialog, messagebox
# Variable calc
operador = ''
precios_comida = [1.32, 1.65, 2.31, 3.22, 1.22, 1.99, 2.05, 2.65, 2.70]
precios_bebida = [0.25, 0.99, 1.21, 1.54, 1.08, 1.10, 2.00, 1.58, 1.70]
precios_postre = [1.54, 1.68, 1.32, 1.97, 2.55, 2.14, 1.94, 1.74, 1.80]
# Funciones
def click_boton(numero):
"""
Función para extraer string de los botones
"""
# Hacemos global la variable operador
global operador
# Añadir la nueva insercción a la variable operador
operador = operador + numero
# Antes de introducir el número se debe borrar lo que guarda
# del click anterior
visor_calculadora.delete(0, END)
# Mostrar en el campo visor lo que contiene la variable operador
visor_calculadora.insert(END, operador)
def borrar():
"""
Función para borrar de calculadora a través del botón
"""
# Hacemos global la variable operador
# y reseteamos el operador
global operador
operador = ''
# Ahora borramos el contenido del visor
visor_calculadora.delete(0, END)
def obtener_resultado():
"""
Mostrar en visor calculadora el resultado de la operación guardada
"""
global operador
# Primero evaluamos operador para extraer el resultado,
# lo metemos en un string y guardamos en nueva variable
resultado = str(eval(operador))
# Ahora borramos el contenido del visor
visor_calculadora.delete(0, END)
# e introducimos el contenido variable resultado al visor
visor_calculadora.insert(0, resultado)
# Por último reseteamos el operador
operador = ''
def revisar_check():
"""
Revisará si algún checkbox tiene contenido
"""
# Checkear comidas
# Contador de los índices de las listas de checkbox
x = 0
# Comprobar cada cuadro comida
for c in cuadros_comida:
# Si el checkbox está en True
if variables_comida[x].get() == 1:
# Habilitar el cuadro
cuadros_comida[x].config(state=NORMAL)
# Eliminar el 0 inicial del visor
if cuadros_comida[x].get() == '0':
cuadros_comida[x].delete(0, END)
# Quede el focus en el visor
cuadros_comida[x].focus()
# Si el checkbox está en False
else:
# Deshabilitar el cuadro
cuadros_comida[x].config(state=DISABLED)
# Setear a cero el visor
texto_comida[x].set('0')
# Sumarle un valor al contador
x += 1
# Checkear bebidas
# Contador de los índices de las listas de checkbox
x = 0
# Comprobar cada cuadro bebida
for c in cuadros_bebida:
# Si el checkbox está en True
if variables_bebida[x].get() == 1:
# Habilitar el cuadro
cuadros_bebida[x].config(state=NORMAL)
# Eliminar el 0 inicial del visor
if cuadros_bebida[x].get() == '0':
cuadros_bebida[x].delete(0, END)
# Quede el focus en el visor
cuadros_bebida[x].focus()
# Si el checkbox está en False
else:
# Deshabilitar el cuadro
cuadros_bebida[x].config(state=DISABLED)
# Setear a cero el visor
texto_bebida[x].set('0')
# Sumarle un valor al contador
x += 1
# Checkear postres
# Contador de los índices de las listas de checkbox
x = 0
# Comprobar cada cuadro postre
for c in cuadros_postre:
# Si el checkbox está en True
if variables_postre[x].get() == 1:
# Habilitar el cuadro
cuadros_postre[x].config(state=NORMAL)
# Eliminar el 0 inicial del visor
if cuadros_postre[x].get() == '0':
cuadros_postre[x].delete(0, END)
# Quede el focus en el visor
cuadros_postre[x].focus()
# Si el checkbox está en False
else:
# Deshabilitar el cuadro
cuadros_postre[x].config(state=DISABLED)
# Setear a cero el visor
texto_postre[x].set('0')
# Sumarle un valor al contador
x += 1
def total():
"""
Calculos del total de comidas, bebidas y postres seleccionados
multiplicarlos por el precio de los items
hacer un subtotal
calcular los impuestos
Total items
Total final
"""
# Comida
# Variable guardar subtotal
subtotal_comida = 0
# Contador indice
p = 0
for cantidad in texto_comida:
subtotal_comida = subtotal_comida + \
(float(cantidad.get()) * precios_comida[p])
p += 1
# Bebida
# Variable guardar subtotal
subtotal_bebida = 0
# Contador indice
p = 0
for cantidad in texto_bebida:
subtotal_bebida = subtotal_bebida + \
(float(cantidad.get()) * precios_bebida[p])
p += 1
# Postre
# Variable guardar subtotal
subtotal_postre = 0
# Contador indice
p = 0
for cantidad in texto_postre:
subtotal_postre = subtotal_postre + \
(float(cantidad.get()) * precios_postre[p])
p += 1
# Guardar en variables calculos de subtotal, impuestos y total
subtotal = subtotal_comida + subtotal_bebida + subtotal_postre
impuestos = subtotal * 0.1
total = subtotal + impuestos
# Asignar a las variables de costos los calculos que corresponda
var_costo_comida.set(f'{round(subtotal_comida, 2)}')
var_costo_bebida.set(f'{round(subtotal_bebida, 2)}')
var_costo_postre.set(f'{round(subtotal_postre, 2)}')
var_subtotal.set(f'{round(subtotal, 2)}')
var_impuesto.set(f'{round(impuestos, 2)}')
var_total.set(f'{round(total, 2)}')
def recibo():
"""
Calcular el recibo con:
- Número de recibo (random)
- Fecha (datetime)
- todos los elementos seleccionados y su precio
- Subtotal, impuestos y total
"""
# Antes de comenzar debemos asegurar que el visor está en blanco
texto_recibo.delete(1.0, END)
# Variable núm. recibo
num_recibo = f'N# - {random.randint(1000, 9999)}'
# Variable fecha y su formato
fecha = datetime.datetime.now()
fecha_recibo = f'{fecha.day}/{fecha.month}/{fecha.year} - {fecha.hour}:{fecha.minute}'
texto_recibo.insert(END, f'Datos:\t{num_recibo}\t\t{fecha_recibo}\n')
texto_recibo.insert(END, f'*' * 47 + '\n')
texto_recibo.insert(END, 'Descripción\t\t\tCant.\tPrecio\n')
texto_recibo.insert(END, f'-' * 68 + '\n')
# Contador de registros comida
x = 0
for comida in texto_comida:
if comida.get() != '0':
texto_recibo.insert(
END,
f'{lista_comidas[x]}\t\t\t{comida.get()}\t{int(comida.get()) * precios_comida[x]}\n'
)
x += 1
# Contador de registros bebida
x = 0
for bebida in texto_bebida:
if bebida.get() != '0':
texto_recibo.insert(
END,
f'{lista_bebidas[x]}\t\t\t{bebida.get()}\t{int(bebida.get()) * precios_bebida[x]}\n'
)
x += 1
# Contador de registros postre
x = 0
for postre in texto_postre:
if postre.get() != '0':
texto_recibo.insert(
END,
f'{lista_postres[x]}\t\t\t{postre.get()}\t{int(postre.get()) * precios_postre[x]}\n'
)
x += 1
texto_recibo.insert(END, f'-' * 68 + '\n')
texto_recibo.insert(
END, f' Total de la comida: \t\t\t{var_costo_comida.get()}\n')
texto_recibo.insert(
END, f' Total de la bebida: \t\t\t{var_costo_bebida.get()}\n')
texto_recibo.insert(
END, f' Total de la postre: \t\t\t{var_costo_postre.get()}\n')
texto_recibo.insert(END, f'-' * 68 + '\n')
texto_recibo.insert(
END, f' Subtotal: \t\t\t{var_subtotal.get()}\n')
texto_recibo.insert(
END, f' Impuestos 10%: \t\t\t{var_impuesto.get()}\n')
texto_recibo.insert(
END, f' Total: \t\t\t{var_total.get()}\n')
texto_recibo.insert(END, f'*' * 47 + '\n')
texto_recibo.insert(END, '\tLe esperamos pronto')
def guardar():
"""
Guardar en un fichero el recibo
Utilizaremos filedialog, messagebox de tkinter
"""
# Variable con la información que tenemos en el recibo
info_recibo = texto_recibo.get(1.0, END)
# Variable con el archivo del elemento pidiendo que se guarde como archivo
# Especificamos que escriba y por defecto la extensión
archivo = filedialog.asksaveasfile(mode='w', defaultextension='.txt')
# Escribimos en el fichero
archivo.write(info_recibo)
archivo.close()
# Informamos al usuario que se ha guardado
# con un cuadro de dialogo
messagebox.showinfo('Información', 'Su recibo se ha guardado')
def resetear():
"""
Borrar todos los campos
"""
# Borrar campo recibo
texto_recibo.delete(0.1, END)
# Borrar campo comidas, bebidas y postres
for texto in texto_comida:
texto.set('0')
for texto in texto_bebida:
texto.set('0')
for texto in texto_postre:
texto.set('0')
# Desactivar cuadros visores comidas, bebidas y postres
for cuadro in cuadros_comida:
cuadro.config(state=DISABLED)
for cuadro in cuadros_bebida:
cuadro.config(state=DISABLED)
for cuadro in cuadros_postre:
cuadro.config(state=DISABLED)
# Desactivar checkbox comidas, bebidas y postres
for v in variables_comida:
v.set(0)
for v in variables_bebida:
v.set(0)
for v in variables_postre:
v.set(0)
# Desactivar todos los costos
var_costo_comida.set('')
var_costo_bebida.set('')
var_costo_postre.set('')
var_subtotal.set('')
var_impuesto.set('')
var_total.set('')
"""
Configuración de la aplicación
"""
# Iniciar tkinter en una variable
aplicacion = Tk()
# Ajustar el tamaño de la ventana y su ubicación
# Tamaño, eje x y eje y
aplicacion.geometry('1250x550+600+200')
# Evitar maximizar pantalla
# eje x y eje y
aplicacion.resizable(0, 0)
# Titulo de la ventana
aplicacion.title('Mi restaurant - Sistema de facturación')
# Color de fondo
aplicacion.config(bg='burlywood')
"""
Configuración de los paneles
"""
# PANEL SUPERIOR
# Configuración de la ubicación, del borde
# y el tipo de relieve
panel_superior = Frame(
aplicacion,
bd=1,
relief=FLAT
)
# Posición dentro de la ubicación
panel_superior.pack(side=TOP)
# Etiqueta título
etiqueta_titulo = Label(
panel_superior,
text='Sistema de Facturación',
fg='gray25',
font=('Ubuntu', 46),
bg='burlywood',
width=27
)
# Posición del título mediante fila y columna
etiqueta_titulo.grid(row=0, column=0)
# PANEL IZQUIERDO
# Configuración de la ubicación, del borde
# y el tipo de relieve
panel_izquierdo = Frame(
aplicacion,
bd=11,
relief=FLAT
)
# Posición dentro de la ubicación
panel_izquierdo.pack(side=LEFT)
# PANEL INFERIOR
# dentro de panel izquierdo - COSTOS
# Configuración de la ubicación, del borde
# y el tipo de relieve
panel_costos = Frame(
panel_izquierdo,
bd=10,
relief=FLAT,
bg='azure4',
padx=50
)
# Posición dentro de la ubicación
panel_costos.pack(side=BOTTOM)
# PANEL IZQUIERDO IZQUIERDA
# dentro de panel izquierdo - COMIDAS
# Configuración de la ubicación, del borde
# y el tipo de relieve. Pero con LabelFrame...
panel_comidas = LabelFrame(
panel_izquierdo,
text='Comida',
font=('Ubuntu', 18, 'bold'),
bd=5,
relief=FLAT,
fg='gray25'
)
# Posición dentro de la ubicación
panel_comidas.pack(side=LEFT)
# PANEL IZQUIERDO CENTRO
# dentro de panel izquierdo - BEBIDAS
# Configuración de la ubicación, del borde
# y el tipo de relieve. Pero con LabelFrame...
panel_bebidas = LabelFrame(
panel_izquierdo,
text='Bebidas',
font=('Ubuntu', 18, 'bold'),
bd=5,
relief=FLAT,
fg='gray25'
)
# Posición dentro de la ubicación
# Se coloca después del anterior
panel_bebidas.pack(side=LEFT)
# PANEL IZQUIERDO DERECHA
# dentro de panel izquierdo - POSTRES
# Configuración de la ubicación, del borde
# y el tipo de relieve. Pero con LabelFrame...
panel_postres = LabelFrame(
panel_izquierdo,
text='Postres',
font=('Ubuntu', 18, 'bold'),
bd=5,
relief=FLAT,
fg='gray25'
)
# Posición dentro de la ubicación
# Se coloca después del anterior
panel_postres.pack(side=LEFT)
# PANEL DERECHO
# Configuración de la ubicación, del borde
# y el tipo de relieve
panel_derecha = Frame(
aplicacion,
bd=1,
relief=FLAT
)
# Posición dentro de la ubicación
panel_derecha.pack(side=RIGHT)
# PANEL DERECHO SUPERIOR
# dentro de panel derecho - CALCULADORA
# Configuración de la ubicación, del borde
# y el tipo de relieve.
panel_calculadora = Frame(
panel_derecha,
bd=1,
relief=FLAT,
bg='burlywood'
)
# Posición dentro de la ubicación
# Por defecto, se coloca arriba
panel_calculadora.pack()
# PANEL DERECHO CENTRO
# dentro de panel derecho - RECIBO
# Configuración de la ubicación, del borde
# y el tipo de relieve.
panel_recibo = Frame(
panel_derecha,
bd=1,
relief=FLAT,
bg='burlywood'
)
# Posición dentro de la ubicación
# Por defecto, se coloca arriba después del anterior
panel_recibo.pack()
# PANEL DERECHO INFERIOR
# dentro de panel derecho - BOTONES
# Configuración de la ubicación, del borde
# y el tipo de relieve.
panel_botones = Frame(
panel_derecha,
bd=1,
relief=FLAT,
bg='burlywood'
)
# Posición dentro de la ubicación
# Por defecto, se coloca arriba después del anterior
panel_botones.pack()
"""
Configuración de los contenidos
"""
# Lista de productos
lista_comidas = [
'pollo',
'cordero',
'salmon',
'merluza',
'verdura',
'kebab',
'pizza1',
'pizza2',
'pizza3'
]
lista_bebidas = [
'agua',
'soda',
'jugo',
'refresco1',
'refresco2',
'cerveza1',
'cerveza2',
'vino1',
'vino2'
]
lista_postres = [
'helado',
'fruta',
'brownie',
'yogur',
'flan',
'mouse',
'pastel1',
'pastel2',
'pastel3'
]
"""
Configuración de las listas de contenidos, checkbox y campos de entrada
"""
# GENERAR ITEMS COMIDA
# Variable de lista dinámica para recoger el valor
# true o false (1 o 0) de cada comida
variables_comida = []
# Se necesitara almacenar el número de elementos solicitados
# para eso un cuadro y el texto que contenga
cuadros_comida = []
texto_comida = []
# Variable de contador para el loop
contador = 0
# Creación de Checkbutton mediante loop
for comida in lista_comidas:
# Creamos el espacio string vacío en la lista
variables_comida.append('')
# Entramos en el espacio vacío
# y le asignamos el valor Intenger Variable de tkinter
variables_comida[contador] = IntVar()
# Check de cada elemento
comida = Checkbutton(
panel_comidas,
text=comida.title(),
font=('Ubuntu', 16, 'bold'),
fg='gray40',
onvalue=1, # Valor cuando este activada
offvalue=0, # Valor cuando este desactivado
variable=variables_comida[contador], # Le damos el valor del check
command=revisar_check # Llamada a la función
)
# Ubicación de la lista con checks
comida.grid(
row=contador,
column=0,
sticky=W
)
# Crear cuadros de entrada de texto
# Creamos el espacio string vacío en las listas
cuadros_comida.append('')
texto_comida.append('')
# Valor por defecto en el cuadro de texto con StringVar de tkinter
texto_comida[contador] = StringVar()
texto_comida[contador].set('0')
# Añadimos un cuadro de entrada tkinter
cuadros_comida[contador] = Entry(
panel_comidas,
font=('Ubuntu', 16, 'bold'),
bd=1,
width=6,
state=DISABLED, # A priori lo desactivamos hasta que no este el checkbox
# Asociamos el cuadro input a la variable
textvariable=texto_comida[contador]
)
# Ubicación de los cuadros de inputs
cuadros_comida[contador].grid(row=contador, column=1)
# Sumar al contador
contador += 1
# GENERAR ITEMS BEBIDA
# Variable de lista dinámica para recoger el valor
# true o false (1 o 0) de cada bebida
variables_bebida = []
# Se necesitara almacenar el número de elementos solicitados
# para eso un cuadro y el texto que contenga
cuadros_bebida = []
texto_bebida = []
# Variable de contador para el loop
contador = 0
# Creación de Checkbutton mediante loop
for bebida in lista_bebidas:
# Creamos el espacio string vacío en la lista
variables_bebida.append('')
# Entramos en el espacio vacío
# y le asignamos el valor Intenger Variable
variables_bebida[contador] = IntVar()
# Check de cada elemento
bebida = Checkbutton(
panel_bebidas,
text=bebida.title(),
font=('Ubuntu', 16, 'bold'),
fg='gray40',
onvalue=1, # Valor cuando este activada
offvalue=0, # Valor cuando este desactivado
variable=variables_bebida[contador], # Le damos el valor del check
command=revisar_check # Llamada a la función
)
# Ubicación de la lista con checks
bebida.grid(
row=contador,
column=0,
sticky=W
)
# Crear cuadros de entrada de texto
# Creamos el espacio string vacío en las listas
cuadros_bebida.append('')
texto_bebida.append('')
# Valor por defecto en el cuadro de texto con StringVar de tkinter
texto_bebida[contador] = StringVar()
texto_bebida[contador].set('0')
# Añadimos un cuadro de entrada tkinter
cuadros_bebida[contador] = Entry(
panel_bebidas,
font=('Ubuntu', 16, 'bold'),
bd=1,
width=6,
state=DISABLED, # A priori lo desactivamos hasta que no este el checkbox
# Asociamos el cuadro input a la variable
textvariable=texto_bebida[contador]
)
# Ubicación de los cuadros de inputs
cuadros_bebida[contador].grid(row=contador, column=1)
# Sumar al contador
contador += 1
# GENERAR ITEMS POSTRES
# Variable de lista dinámica para recoger el valor
# true o false (1 o 0) de cada postre
variables_postre = []
# Se necesitara almacenar el número de elementos solicitados
# para eso un cuadro y el texto que contenga
cuadros_postre = []
texto_postre = []
# Variable de contador para el loop
contador = 0
# Creación de Checkbutton mediante loop
for postre in lista_postres:
# Creamos el espacio string vacío en la lista
variables_postre.append('')
# Entramos en el espacio vacío
# y le asignamos el valor Intenger Variable
variables_postre[contador] = IntVar()
# Check de cada elemento
postre = Checkbutton(
panel_postres,
text=postre.title(),
font=('Ubuntu', 16, 'bold'),
fg='gray40',
onvalue=1, # Valor cuando este activada
offvalue=0, # Valor cuando este desactivado
variable=variables_postre[contador], # Le damos el valor del check
command=revisar_check # Llamada a la función
)
# Ubicación de la lista con checks
postre.grid(
row=contador,
column=0,
sticky=W
)
# Crear cuadros de entrada de texto
# Creamos el espacio string vacío en las listas
cuadros_postre.append('')
texto_postre.append('')
# Valor por defecto en el cuadro de texto con StringVar de tkinter
texto_postre[contador] = StringVar()
texto_postre[contador].set('0')
# Añadimos un cuadro de entrada tkinter
cuadros_postre[contador] = Entry(
panel_postres,
font=('Ubuntu', 16, 'bold'),
bd=1,
width=6,
state=DISABLED, # A priori lo desactivamos hasta que no este el checkbox
# Asociamos el cuadro input a la variable
textvariable=texto_postre[contador]
)
# Ubicación de los cuadros de inputs
cuadros_postre[contador].grid(row=contador, column=1)
# Sumar al contador
contador += 1
"""
Configurar etiquetas de costos y campos de entrada
"""
# Variables
var_costo_comida = StringVar()
var_costo_bebida = StringVar()
var_costo_postre = StringVar()
var_subtotal = StringVar()
var_impuesto = StringVar()
var_total = StringVar()
# COSTO COMIDA
etiqueta_costo_comida = Label(
panel_costos,
text='Costo Comida',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_costo_comida.grid(row=0, column=0)
texto_costo_comida = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=1,
width=10,
state='readonly',
textvariable=var_costo_comida
)
texto_costo_comida.grid(row=0, column=1, padx=16)
# COSTO BEBIDA
etiqueta_costo_bebida = Label(
panel_costos,
text='Costo Bebida',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_costo_bebida.grid(row=1, column=0)
texto_costo_bebida = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=1,
width=10,
state='readonly',
textvariable=var_costo_bebida
)
texto_costo_bebida.grid(row=1, column=1, padx=16)
# COSTO POSTRE
etiqueta_costo_postre = Label(
panel_costos,
text='Costo Postre',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_costo_postre.grid(row=2, column=0)
texto_costo_postre = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=1,
width=10,
state='readonly',
textvariable=var_costo_postre
)
texto_costo_postre.grid(row=2, column=1, padx=16)
# SUBTOTAL
etiqueta_subtotal = Label(
panel_costos,
text='Subtotal',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_subtotal.grid(row=0, column=2)
texto_subtotal = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=1,
width=10,
state='readonly',
textvariable=var_subtotal
)
texto_subtotal.grid(row=0, column=3, padx=16)
# IMPUESTOS
etiqueta_impuesto = Label(
panel_costos,
text='Impuesto',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_impuesto.grid(row=1, column=2)
texto_impuesto = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=1,
width=10,
state='readonly',
textvariable=var_impuesto
)
texto_impuesto.grid(row=1, column=3, padx=16)
# TOTAL
etiqueta_total = Label(
panel_costos,
text='Total',
font=('Ubuntu', 14, 'bold'),
bg='azure4',
fg='white'
)
etiqueta_total.grid(row=2, column=2)
texto_total = Entry(
panel_costos,
font=('Ubuntu', 14, 'bold'),
bd=2,
width=10,
state='readonly',
textvariable=var_total
)
texto_total.grid(row=2, column=3, padx=16)
"""
Configurar Botones
"""
# Lista de botones
botones = [
'total',
'recibo',
'guardar',
'resetear'
]
botones_creados = []
# Contador de columnas
columnas = 0
for boton in botones:
boton = Button(
panel_botones,
text=boton.title(),
font=('Ubuntu', 14, 'bold'),
fg='white',
bg='CadetBlue',
bd=1,
width=10
)
botones_creados.append(boton)
boton.grid(row=0, column=columnas)
columnas += 1
# Añadir funcionalidad al botón total
botones_creados[0].config(command=total)
botones_creados[1].config(command=recibo)
botones_creados[2].config(command=guardar)
botones_creados[3].config(command=resetear)
"""
Configurar area de recibo
"""
texto_recibo = Text(
panel_recibo,
font=('Ubuntu', 14, 'bold'),
bd=2,
width=50,
height=10
)
texto_recibo.grid(row=0, column=0)
"""
Calculadora
"""
visor_calculadora = Entry(
panel_calculadora,
font=('Ubuntu', 14, 'bold'),
bd=2,
width=50
)
visor_calculadora.grid(
row=0,
column=0,
columnspan=4
)
# Variables de listas
botones_calculadora = [
'7',
'8',
'9',
'+',
'4',
'5',
'6',
'-',
'1',
'2',
'3',
'x',
'=',
'Borrar',
'0',
'/'
]
botones_guardados = []
fila = 1
columna = 0
for boton in botones_calculadora:
boton = Button(
panel_calculadora,
text=boton.title(),
font=('ubuntu', 14, 'bold'),
fg='white',
bg='CadetBlue',
bd=1,
width=10
)
# Guardamos en la lista los botones marcados
botones_guardados.append(boton)
# Ubicamos los botones en el panel
boton.grid(row=fila, column=columna)
if columna == 3:
fila += 1
columna += 1
if columna == 4:
columna = 0
# Añadimos el valor de los botones a la función de click
botones_guardados[0].config(command=lambda: click_boton('7'))
botones_guardados[1].config(command=lambda: click_boton('8'))
botones_guardados[2].config(command=lambda: click_boton('9'))
botones_guardados[3].config(command=lambda: click_boton('+'))
botones_guardados[4].config(command=lambda: click_boton('4'))
botones_guardados[5].config(command=lambda: click_boton('5'))
botones_guardados[6].config(command=lambda: click_boton('6'))
botones_guardados[7].config(command=lambda: click_boton('-'))
botones_guardados[8].config(command=lambda: click_boton('1'))
botones_guardados[9].config(command=lambda: click_boton('2'))
botones_guardados[10].config(command=lambda: click_boton('3'))
botones_guardados[11].config(command=lambda: click_boton('*'))
botones_guardados[12].config(command=obtener_resultado)
botones_guardados[13].config(command=borrar)
botones_guardados[14].config(command=lambda: click_boton('0'))
botones_guardados[15].config(command=lambda: click_boton('/'))
"""
FINAL - Se debe mantener abierta la pantalla hasta el final
"""
# Evitar que la pantalla se cierre
aplicacion.mainloop()