Skip to content

Instantly share code, notes, and snippets.

@sexnine
Created May 20, 2022 01:26
Show Gist options
  • Save sexnine/597a75da34a9f8723dba648a89fb0c84 to your computer and use it in GitHub Desktop.
Save sexnine/597a75da34a9f8723dba648a89fb0c84 to your computer and use it in GitHub Desktop.
GUI temperature converter made in Python using Tk
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