diff --git a/calc.py b/calculator.py similarity index 56% rename from calc.py rename to calculator.py index 758bc87..6c3b0cd 100644 --- a/calc.py +++ b/calculator.py @@ -1,9 +1,12 @@ import tkinter as tk +# Define two font size sets LARGE_FONT_STYLE = ("Arial", 40, "bold") -SMALL_FONT_STYLE = ("Arial", 16) -DIGITS_FONT_STYLE = ("Arial", 24, "bold") -DEFAULT_FONT_STYLE = ("Arial", 20) +SMALL_FONT_STYLE = ("Arial", 20) +DIGITS_FONT_STYLE_LARGE = ("Arial", 24, "bold") +DIGITS_FONT_STYLE_SMALL = ("Arial", 16, "bold") +DEFAULT_FONT_STYLE_LARGE = ("Arial", 20) +DEFAULT_FONT_STYLE_SMALL = ("Arial", 12) OFF_WHITE = "#F8FAFF" WHITE = "#FFFFFF" @@ -11,7 +14,6 @@ LIGHT_GRAY = "#F5F5F5" LABEL_COLOR = "#25265E" - class Calculator: def __init__(self): self.window = tk.Tk() @@ -19,10 +21,15 @@ def __init__(self): self.window.resizable(0, 0) self.window.title("Calculator") + # Default font setting + self.font_size = tk.StringVar(value="Large") + + self.create_font_selector() + self.total_expression = "" self.current_expression = "" - self.display_frame = self.create_display_frame() + self.display_frame = self.create_display_frame() self.total_label, self.label = self.create_display_labels() self.digits = { @@ -31,6 +38,7 @@ def __init__(self): 1: (3, 1), 2: (3, 2), 3: (3, 3), 0: (4, 2), '.': (4, 1) } + self.operations = {"/": "\u00F7", "*": "\u00D7", "-": "-", "+": "+"} self.buttons_frame = self.create_buttons_frame() @@ -38,38 +46,64 @@ def __init__(self): for x in range(1, 5): self.buttons_frame.rowconfigure(x, weight=1) self.buttons_frame.columnconfigure(x, weight=1) + self.create_digit_buttons() self.create_operator_buttons() self.create_special_buttons() self.bind_keys() + self.window.mainloop() + + def create_font_selector(self): + font_frame = tk.Frame(self.window, bg=WHITE) + font_frame.pack(fill='x', padx=10, pady=5) + + label = tk.Label(font_frame, text="Font Size:", bg=WHITE) + label.pack(side='left') + + font_dropdown = tk.OptionMenu(font_frame, self.font_size, "Small", "Large", command=self.reload_ui) + font_dropdown.pack(side='left') + + def get_fonts(self): + if self.font_size.get() == "Small": + return SMALL_FONT_STYLE, DIGITS_FONT_STYLE_SMALL, DEFAULT_FONT_STYLE_SMALL + return LARGE_FONT_STYLE, DIGITS_FONT_STYLE_LARGE, DEFAULT_FONT_STYLE_LARGE + + def reload_ui(self, _=None): + # Destroy and rebuild display and buttons + self.display_frame.destroy() + self.buttons_frame.destroy() + self.display_frame = self.create_display_frame() + self.total_label, self.label = self.create_display_labels() + self.buttons_frame = self.create_buttons_frame() + for x in range(1, 5): + self.buttons_frame.rowconfigure(x, weight=1) + self.buttons_frame.columnconfigure(x, weight=1) + self.create_digit_buttons() + self.create_operator_buttons() + self.create_special_buttons() + def bind_keys(self): self.window.bind("", lambda event: self.evaluate()) for key in self.digits: self.window.bind(str(key), lambda event, digit=key: self.add_to_expression(digit)) - for key in self.operations: self.window.bind(key, lambda event, operator=key: self.append_operator(operator)) - def create_special_buttons(self): - self.create_clear_button() - self.create_equals_button() - self.create_square_button() - self.create_sqrt_button() - def create_display_labels(self): - total_label = tk.Label(self.display_frame, text=self.total_expression, anchor=tk.E, bg=LIGHT_GRAY, + large_font, _, _ = self.get_fonts() + total_label = tk.Label(self.display_frame, text=self.total_expression, anchor=tk.E, bg=WHITE, fg=LABEL_COLOR, padx=24, font=SMALL_FONT_STYLE) total_label.pack(expand=True, fill='both') - label = tk.Label(self.display_frame, text=self.current_expression, anchor=tk.E, bg=LIGHT_GRAY, - fg=LABEL_COLOR, padx=24, font=LARGE_FONT_STYLE) + label = tk.Label(self.display_frame, text=self.current_expression, anchor=tk.E, bg=WHITE, + fg=LABEL_COLOR, padx=24, font=large_font) label.pack(expand=True, fill='both') return total_label, label def create_display_frame(self): - frame = tk.Frame(self.window, height=221, bg=LIGHT_GRAY) + frame = tk.Frame(self.window, height=221, bg=WHITE) frame.pack(expand=True, fill="both") return frame @@ -77,10 +111,15 @@ def add_to_expression(self, value): self.current_expression += str(value) self.update_label() + def update_label(self): + self.label.config(text=self.current_expression[:11]) + def create_digit_buttons(self): + _, digits_font, _ = self.get_fonts() for digit, grid_value in self.digits.items(): - button = tk.Button(self.buttons_frame, text=str(digit), bg=WHITE, fg=LABEL_COLOR, font=DIGITS_FONT_STYLE, - borderwidth=0, command=lambda x=digit: self.add_to_expression(x)) + button = tk.Button(self.buttons_frame, text=str(digit), bg=WHITE, fg=LABEL_COLOR, + font=digits_font, borderwidth=0, + command=lambda x=digit: self.add_to_expression(x)) button.grid(row=grid_value[0], column=grid_value[1], sticky=tk.NSEW) def append_operator(self, operator): @@ -90,11 +129,16 @@ def append_operator(self, operator): self.update_total_label() self.update_label() + def update_total_label(self): + self.total_label.config(text=self.total_expression) + def create_operator_buttons(self): + _, _, default_font = self.get_fonts() i = 0 for operator, symbol in self.operations.items(): - button = tk.Button(self.buttons_frame, text=symbol, bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, - borderwidth=0, command=lambda x=operator: self.append_operator(x)) + button = tk.Button(self.buttons_frame, text=symbol, bg=OFF_WHITE, fg=LABEL_COLOR, + font=default_font, borderwidth=0, + command=lambda x=operator: self.append_operator(x)) button.grid(row=i, column=4, sticky=tk.NSEW) i += 1 @@ -104,64 +148,32 @@ def clear(self): self.update_label() self.update_total_label() - def create_clear_button(self): - button = tk.Button(self.buttons_frame, text="C", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, - borderwidth=0, command=self.clear) - button.grid(row=0, column=1, sticky=tk.NSEW) - - def square(self): - self.current_expression = str(eval(f"{self.current_expression}**2")) - self.update_label() - - def create_square_button(self): - button = tk.Button(self.buttons_frame, text="x\u00b2", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, - borderwidth=0, command=self.square) - button.grid(row=0, column=2, sticky=tk.NSEW) - - def sqrt(self): - self.current_expression = str(eval(f"{self.current_expression}**0.5")) - self.update_label() - - def create_sqrt_button(self): - button = tk.Button(self.buttons_frame, text="\u221ax", bg=OFF_WHITE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, - borderwidth=0, command=self.sqrt) - button.grid(row=0, column=3, sticky=tk.NSEW) - def evaluate(self): self.total_expression += self.current_expression - self.update_total_label() try: self.current_expression = str(eval(self.total_expression)) - self.total_expression = "" except Exception as e: self.current_expression = "Error" finally: self.update_label() + self.update_total_label() + + def create_special_buttons(self): + _, _, default_font = self.get_fonts() + clear_button = tk.Button(self.buttons_frame, text="C", bg=LIGHT_GRAY, fg=LABEL_COLOR, + font=default_font, borderwidth=0, command=self.clear) + clear_button.grid(row=0, column=1, sticky=tk.NSEW) - def create_equals_button(self): - button = tk.Button(self.buttons_frame, text="=", bg=LIGHT_BLUE, fg=LABEL_COLOR, font=DEFAULT_FONT_STYLE, - borderwidth=0, command=self.evaluate) - button.grid(row=4, column=3, columnspan=2, sticky=tk.NSEW) + equals_button = tk.Button(self.buttons_frame, text="=", bg=LIGHT_BLUE, fg=LABEL_COLOR, + font=default_font, borderwidth=0, command=self.evaluate) + equals_button.grid(row=0, column=2, columnspan=2, sticky=tk.NSEW) def create_buttons_frame(self): frame = tk.Frame(self.window) frame.pack(expand=True, fill="both") return frame - def update_total_label(self): - expression = self.total_expression - for operator, symbol in self.operations.items(): - expression = expression.replace(operator, f' {symbol} ') - self.total_label.config(text=expression) - - def update_label(self): - self.label.config(text=self.current_expression[:11]) - - def run(self): - self.window.mainloop() - if __name__ == "__main__": - calc = Calculator() - calc.run() + Calculator()