Mar-05-2022, 07:11 AM
(This post was last modified: Mar-05-2022, 07:11 AM by deanhystad.)
Here is my temperature converter using my temperature class. I didn't have to make any changes to the Temperature class to use it in the GUI program (I added some more units for fun). The Temperature class is responsible for doing the unit conversion, and the GUI is responsible for getting user input, calling the Temperature methods to do the conversion, and displaying the results. I think your biggest problem was that you mashed all this together and there was no clear definition of who was responsible for what.
""" Temperature converter panel. Enter temperature in entry. Specify units for the "input" temperature and the tempeerature display. Converted temperatur appears in label. """ import enum import tkinter as tk from tkinter import ttk ###### THIS IS THE TEMPERATURE CLASS PART ###### class Temperature: """I am a temperature. You can specify my units. I do unit conversion""" # Temperature unts and unit conversion information. All temperatures are # converted to and from Celsius regardless of the specified or default units. class Unit(enum.Enum): CELSIUS = "C" FAHRENHEIT = "F" KELVIN = "K" RANKINE = "Ra" REAUMER = "R" # Convert from unit to Celsius convert_from = { Unit.CELSIUS: lambda x: x, Unit.KELVIN: lambda x: x - 273.15, Unit.FAHRENHEIT: lambda x: (x - 32) / 1.8, Unit.RANKINE: lambda x: (x - 491.67) / 1.8, Unit.REAUMER: lambda x: x * 1.25 } # convert from Celsius to unit convert_to = { Unit.CELSIUS: lambda x: x, Unit.KELVIN: lambda x: x + 273.15, Unit.FAHRENHEIT: lambda x: x * 1.8 + 32, Unit.RANKINE: lambda x: x * 1.8 + 491.67, Unit.REAUMER: lambda x: x * 0.8 } def __init__(self, value=None, unit=Unit.CELSIUS): self.units = unit self.set(0 if value is None else value) def set(self, value, unit=None): """Set temperature value. Can specify unit for value.""" if unit is None: unit = self.units self.degreesC = self.convert_from[unit](value) return self.degreesC def set_units(self, units): """Change the default temperature units""" self.units = units def get(self, unit=None): """Get temperature value. Can specify unit for value.""" if unit is None: unit = self.units return self.convert_to[unit](self.degreesC) def __str__(self): """Get str for printing.""" return f"{self.get()} °{self.units.value:0.2f}" ###### THIS IS THE GRAPHICAL USER INTERFACE PART ###### class TemperatureConverter(tk.Tk): """ Panel that uses Temperature class to do temperature unit conversion Converts temperature from one temperature unit to another. """ def __init__(self, *args, **kvargs): super().__init__(*args, **kvargs) self.wm_title("Temperature Converter") self.temperature = Temperature() self.units = {unit.name:unit for unit in self.temperature.Unit} unit_names = list(self.units.keys()) tk.Label(self, text="Convert").pack(padx=5, pady=5, side=tk.LEFT) # "from" temperature widgets self.from_units = tk.StringVar(value=unit_names[0]) self.from_value = tk.DoubleVar(value=0.0) tk.Entry(self, textvariable=self.from_value, width=8, justify=tk.RIGHT) \ .pack(padx=5, pady=5, side=tk.LEFT) ttk.Combobox(self, textvariable=self.from_units, values=unit_names, width=12) \ .pack(padx=5, pady=5, side=tk.LEFT) tk.Label(self, text="to").pack(padx=5, pady=5, side=tk.LEFT) # "to" temperature widgets self.to_units = tk.StringVar(value=unit_names[0]) self.to_value = tk.StringVar(value="0.00") tk.Label(self, textvariable=self.to_value, width=8, anchor=tk.E).pack(padx=5, pady=5, side=tk.LEFT) ttk.Combobox(self, textvariable=self.to_units, values=unit_names, width=12) \ .pack(padx=5, pady=5, side=tk.LEFT) # Bind variable write event to convert method. Convert method ignores arguments for var in (self.from_value, self.from_units, self.to_units): var.trace("w", self.convert) def convert(self, *_): """Peform temperature unit conversion""" try: degrees = self.from_value.get() self.temperature.set(degrees, self.units[self.from_units.get()]) degrees = self.temperature.get(self.units[self.to_units.get()]) self.to_value.set(f"{degrees:0.2F}") except tk.TclError: self.to_value.set("-NA-") TemperatureConverter().mainloop()