from tkinter import * from tkinter import ttk status = 1 # 1 - neue Eingabe, 2 - Eingabe verarbeitet def switch_status(new_status: int = None): """ Verändert den globalen Status :param new_status: neuer Statuswert :return: None """ global status if not new_status: if status == 1: status = 2 else: status = 1 else: status = new_status update_statusbar() def update_statusbar(): """ Passt die Farbe der Statuszeile an den Status an. :return: None """ global status if status == 1: frame_statusbar['style'] = 'aFrame.TFrame' elif status == 2: frame_statusbar['style'] = 'bFrame.TFrame' else: frame_statusbar['style'] = 'bFrame.TFrame' def calculate(*args): """ Berechnet aus der eingegebenen Länge in feet die Länge in Metern. :param args: :return: None """ try: stringvalue = feet.get() stringvalue = stringvalue.replace(",", ".") value = float(stringvalue) m_value = 0.3048 * value m_value = round(m_value, 2) meters.set(m_value) switch_status(2) except ValueError: pass return True def check_entry(what: str = ""): """ Validiert, ob Eingabe leer oder eine Fließkommazahl ist. :param what: str eingegebene Zeichenkette :return: boolean """ switch_status(1) if what == "": # Nichts eingegeben return True else: try: # DEBUG print(what) what = what.replace(',', '.') float(what) return True except ValueError: return False # Hauptfenster root = Tk() root.title("Feet to Meters") check_entry_wrapper = root.register(check_entry) # Rahmen im Hauptfenster (aus ttk für Farbanpassung) mainframe = ttk.Frame(root, padding="3 3 12 12") mainframe.grid(column=0, row=0, sticky=NW) root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) # Eingabefeld für Länge in feet feet = StringVar() feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet, validatecommand=(check_entry_wrapper, '%P'), validate='key') feet_entry.grid(column=2, row=1, sticky=W + E) # Einheit-Label für Eingabefeld der Länge in feet ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W) # Label für Ausgabefeld der Länge in Metern ttk.Label(mainframe, text="ist äquivalent zu").grid(column=1, row=2, sticky=E) # Einheit-Label für Ausgabefeld der Länge in Metern ttk.Label(mainframe, text="Meter").grid(column=3, row=2, sticky=W) # Ausgabefeld für Länge in Metern meters = StringVar() meters_entry = ttk.Entry(mainframe, width=7, textvariable=meters) meters_entry.grid(column=2, row=2, sticky=(W, E)) meters_entry.configure(state='readonly') # keine Eingabe, aber selektierbar # Button für Berechnung button_calc = ttk.Button(mainframe, text="Berechne", command=calculate) button_calc.grid(column=3, row=3, sticky=W) # schönere Abstände for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5) # Statusbar s = ttk.Style() s.configure('aFrame.TFrame', background="yellow") s.configure('bFrame.TFrame', background="green") s.configure('cFrame.TFrame', background="red") frame_statusbar = ttk.Frame(root) frame_statusbar['relief'] = 'sunken' frame_statusbar['height'] = 12 frame_statusbar['style'] = 'aFrame.TFrame' frame_statusbar.grid_propagate(0) # Feste Größe an Grid-Packer weitergeben frame_statusbar.grid(column=0, row=1, sticky=W + S + E) # Setze Fokus in Eingabefeld feet_entry.focus() root.bind("", calculate) root.bind("", calculate) root.mainloop()