Created
May 20, 2022 01:26
-
-
Save sexnine/597a75da34a9f8723dba648a89fb0c84 to your computer and use it in GitHub Desktop.
GUI temperature converter made in Python using Tk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import tkinter as tk | |
from typing import Callable, Optional | |
def is_number_text(text): | |
if text in ["", "-"]: | |
return True | |
try: | |
float(text) | |
return True | |
except ValueError: | |
return False | |
class Conversions: | |
@staticmethod | |
def f_to_c(x: float) -> float: | |
return (x - 32) * 5 / 9 | |
@staticmethod | |
def c_to_f(x: float) -> float: | |
return (x * 9 / 5) + 32 | |
@staticmethod | |
def c_to_k(x: float) -> float: | |
return x + 273.15 | |
@staticmethod | |
def k_to_c(x: float) -> float: | |
return x - 273.15 | |
@staticmethod | |
def f_to_k(x: float) -> float: | |
return Conversions.c_to_k(Conversions.f_to_c(x)) | |
@staticmethod | |
def k_to_f(x: float) -> float: | |
return Conversions.c_to_f(Conversions.k_to_c(x)) | |
class ReactiveEntry(tk.Entry): | |
def __init__(self, *args, on_updated: Callable[[str, str, bool], None], value_check: Callable[[str], bool], **kwargs): | |
self.var = tk.StringVar() | |
self.last_value = "" | |
self.on_updated = on_updated | |
self.value_check = value_check | |
self.just_set = False | |
super().__init__(textvariable=self.var, *args, **kwargs) | |
self.var.trace("w", self._var_updated) | |
def _var_updated(self, *args): | |
new_val = self.var.get() | |
if not self.value_check(new_val): | |
self.var.set(self.last_value) | |
return | |
self.on_updated(self.last_value, new_val, not self.just_set) | |
self.just_set = False | |
self.last_value = new_val | |
def set(self, value): | |
self.just_set = True | |
self.var.set(value) | |
self.last_value = value | |
class App: | |
def __init__(self): | |
self.root = tk.Tk() | |
self.root.title("Temperature Converter") | |
self.f_entry: Optional[ReactiveEntry] = None | |
self.c_entry: Optional[ReactiveEntry] = None | |
self.k_entry: Optional[ReactiveEntry] = None | |
self.ui_stuff() | |
self.root.mainloop() | |
def ui_stuff(self): | |
tk.Label(self.root, text="Fahrenheit").pack() | |
self.f_entry = ReactiveEntry(self.root, on_updated=self.handle_f_change, value_check=is_number_text) | |
self.f_entry.pack() | |
tk.Label(self.root, text="Celsius").pack() | |
self.c_entry = ReactiveEntry(self.root, on_updated=self.handle_c_change, value_check=is_number_text) | |
self.c_entry.pack() | |
tk.Label(self.root, text="Kelvin").pack() | |
self.k_entry = ReactiveEntry(self.root, on_updated=self.handle_k_change, value_check=is_number_text) | |
self.k_entry.pack() | |
def handle_f_change(self, before, after, user_change): | |
if user_change: | |
self.handle_change(after, self.c_entry, Conversions.f_to_c) | |
self.handle_change(after, self.k_entry, Conversions.f_to_k) | |
def handle_c_change(self, before, after, user_change): | |
if user_change: | |
self.handle_change(after, self.f_entry, Conversions.c_to_f) | |
self.handle_change(after, self.k_entry, Conversions.c_to_k) | |
def handle_k_change(self, before, after, user_change): | |
if user_change: | |
self.handle_change(after, self.f_entry, Conversions.k_to_f) | |
self.handle_change(after, self.c_entry, Conversions.k_to_c) | |
@staticmethod | |
def handle_change(value: str, element: ReactiveEntry, equation: Callable[[float], float]) -> None: | |
val = "" | |
try: | |
value = float(value) | |
except ValueError: | |
pass | |
else: | |
val = str(round(equation(value), 1)) | |
element.set(val) | |
if __name__ == "__main__": | |
App() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment