Software architecture — MVC

from tkinter import *root = Tk()formula=""
equation = StringVar()
calculation = Label(root, textvariable=equation)equation.set("0")calculation.grid(columnspan=4)#Creating buttons & functionsdef button_press(num):
# We create a gloabl variable that will be updated whenever the button is pressed
global formula
formula = formula + str(num)
equation.set(formula)
def equal_button():
# We will need to use eval() to evaluate equation string and do the math
global formula
total = str(eval(formula))
equation.set(total)
formula=""
def clear_button():
global formula
formula = ""
equation.set(formula)
button_1 = Button(root, text="1", command=lambda: button_press(1))
button_1.grid(row=1, column=0)
button_2 = Button(root, text="2", command=lambda: button_press(2))
button_2.grid(row=1, column=1)
... # And so onbutton_plus = Button(root, text="+", command=lambda: button_press("+"))
button_plus.grid(row=1, column=3)
... # And so onbutton_clear = Button(root, text="C", command=clear_button)
button_clear.grid(row=4, column=1)
root.mainloop()

The Model

class Model:
def __init__(self):
self.input_str: str = ""
@property
def data(self) -> str:
return self.input_str
@data.setter
def data(self, value) -> None:
self.input_str = value

The View

from tkinter import *
from typing import Callable
...class View:
def __init__(self):
self.root = Tk()
self.equation = StringVar()
def set_equation(self, value: str) -> None:
self.equation.set(value)
def setup_view(self, callback: Callable) -> None:
calculation = Label(self.root, textvariable=self.equation)
self.set_equation("0")
calculation.grid(columnspan=4)
self.setup_buttons(callback)
def setup_buttons(self, callback: Callable) -> None:
button_1 = Button(self.root, text="1", command=lambda: callback("1"))
button_1.grid(row=1, column=0)
button_2 = Button(self.root, text="2", command=lambda: callback("2"))
button_2.grid(row=1, column=1)
... # and so ondef start_main_loop(self) -> None:
self.root.mainloop()

The Controller

class Controller:
def __init__(self, view: View, model: Model):
self.model = model
self.view = view
def start(self) -> None:
"""Set up and start the view"""
self.view.setup_view(self.button_click_handler)
self.view.start_main_loop()
def button_click_handler(self, value: str) -> None:
"""Redirect to the suitable handler function base on the value of the clicked button"""
if value == "=":
self._equal_button()
elif value == "C":
self._clear_button()
else:
self._button_pressed(value)
def _button_pressed(self, num: str) -> None:
"""Add the value of the clicked button to the equation"""
self.model.data += str(num)
self.view.set_equation(self.model.data)
def _equal_button(self) -> None:
"""Evaluate the equation and show the result"""
total = str(eval(self.model.data))
self.view.set_equation(total)
self.model.data = ""
def _clear_button(self) -> None:
"""Clear out the sreen of the calculator"""
self.model.data = ""
self.view.set_equation(self.model.data)
if __name__ == "__main__":
controller = Controller(View(), Model())
controller.start()
src
┣ calculator
┃ ┣ __init__.py
┃ ┣ controllers.py
┃ ┣ models.py
┃ ┗ views.py
┗ main.py

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store