May-30-2024, 08:51 AM
May-30-2024, 09:10 AM
It is a pretty common task. Can you post the code that currently reads the user input where you want to catch and correct the error?
Jun-07-2024, 10:00 AM
(May-30-2024, 09:10 AM)Gribouillis Wrote: [ -> ]It is a pretty common task. Can you post the code that currently reads the user input where you want to catch and correct the error?
The following code takes the user input only as HH:MM otherwise an error occurs and the program stops.
I would like to allow the user to be able to re-enter the input without the program terminating.
import tkinter as tk from tkinter import ttk from tkinter.messagebox import showinfo # root window root = tk.Tk() root.geometry("300x200") root.resizable(False, False) root.title('Time Clock') # store StartofWork address and EndofWork StartofWork = tk.StringVar() EndofWork = tk.StringVar() def login_clicked(): """ callback when the login button clicked """ WorkStart = StartofWork.get() tdelta = timediff() """ msg = f'Start of Shift: {StartofWork.get()} and End of Shift: {EndofWork.get()}' """ msg = f'Total Hours: {tdelta}' showinfo( title='Time Calculated', message=msg ) from datetime import datetime def timediff(): WorkStart = StartofWork.get() """StartTime = input("Enter Start Time in HH:MM\n") """ print("This is WorkStart", WorkStart) print("This is EndofWork", EndofWork.get()) FMT = '%H:%M' tdelta = datetime.strptime(EndofWork.get(), FMT) - datetime.strptime(StartofWork.get(), FMT) return tdelta # Sign in frame signin = ttk.Frame(root) signin.pack(padx=10, pady=10, fill='x', expand=True) # StartofWork StartofWork_label = ttk.Label(signin, text="Clock In:") StartofWork_label.pack(fill='x', expand=True) StartofWork_entry = ttk.Entry(signin, textvariable=StartofWork) StartofWork_entry.pack(fill='x', expand=True) StartofWork_entry.focus() # EndofWork password_label = ttk.Label(signin, text="Clock Out:") password_label.pack(fill='x', expand=True) password_entry = ttk.Entry(signin, textvariable=EndofWork) password_entry.pack(fill='x', expand=True) # login button login_button = ttk.Button(signin, text="Calculate Time", command=login_clicked) login_button.pack(fill='x', expand=True, pady=10) root.mainloop()
Jun-07-2024, 11:26 AM
Please post code using the bbtags. Makes it easier to help.
Is this what you are trying for?
Added a try block
Is this what you are trying for?
Added a try block
import tkinter as tk from tkinter import ttk from tkinter.messagebox import showinfo, showerror from datetime import datetime # root window root = tk.Tk() root.geometry("300x200") root.resizable(False, False) root.title('Time Clock') # store StartofWork address and EndofWork StartofWork = tk.StringVar() EndofWork = tk.StringVar() def login_clicked(): """ callback when the login button clicked """ WorkStart = StartofWork.get() tdelta = timediff() if tdelta: """ msg = f'Start of Shift: {StartofWork.get()} and End of Shift: {EndofWork.get()}' """ msg = f'Total Hours: {tdelta}' showinfo( title='Time Calculated', message=msg ) def timediff(): WorkStart = StartofWork.get() """StartTime = input("Enter Start Time in HH:MM\n") """ print("This is WorkStart", WorkStart) print("This is EndofWork", EndofWork.get()) FMT = '%H:%M' try: tdelta = datetime.strptime(EndofWork.get(), FMT) - datetime.strptime(StartofWork.get(), FMT) return tdelta except ValueError: showerror('Error!', 'Time format is not correct.') # Sign in frame signin = ttk.Frame(root) signin.pack(padx=10, pady=10, fill='x', expand=True) # StartofWork StartofWork_label = ttk.Label(signin, text="Clock In:") StartofWork_label.pack(fill='x', expand=True) StartofWork_entry = ttk.Entry(signin, textvariable=StartofWork) StartofWork_entry.pack(fill='x', expand=True) StartofWork_entry.focus() # EndofWork password_label = ttk.Label(signin, text="Clock Out:") password_label.pack(fill='x', expand=True) password_entry = ttk.Entry(signin, textvariable=EndofWork) password_entry.pack(fill='x', expand=True) # login button login_button = ttk.Button(signin, text="Calculate Time", command=login_clicked) login_button.pack(fill='x', expand=True, pady=10) root.mainloop()
Jun-07-2024, 12:59 PM
I took the liberty and rewrote your code a little
import tkinter as tk from tkinter.messagebox import showerror, showinfo from datetime import datetime class Action: ''' Action class handles all data manipulations and validations ''' def calculate(self, start, end): ''' Calculate time difference ''' # Set format fmt = '%H:%M' # Use try block to get the calculations and return total. If we get a ValueError return False try: tdelta = datetime.strptime(end, fmt) - datetime.strptime(start, fmt) return tdelta except ValueError: return False class Window: ''' Window class handles the window display and presentation ''' def __init__(self, parent): self.parent = parent parent.columnconfigure(0, weight=1) parent.rowconfigure(0, weight=1) parent['padx'] = 4 parent['pady'] = 4 parent.geometry('300x170+300+300') parent.resizable(False, False) parent.title('Time Clock') container = tk.Frame(parent) container['padx'] = 4 container['pady'] = 4 container['highlightbackground'] = '#999999' container['highlightcolor'] = '#999999' container['highlightthickness'] = 1 container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=1) container.grid_columnconfigure(1, weight=3) label = tk.Label(container, bg='#fffccc') label['text'] = 'Time Clock' label['fg'] = 'navy' label['font'] = ('verdana', 25, 'bold') label.grid(column=0, columnspan=2, row=0, sticky='new') label = tk.Label(container, text='Clock In:', anchor='w') label.grid(column=0, row=1, sticky='new', padx=1, pady=5) label = tk.Label(container, text='Clock out:', anchor='w') label.grid(column=0, row=2, sticky='new', padx=1, pady=5) self.in_entry = tk.Entry(container) self.in_entry.grid(column=1, row=1, sticky='new', padx=1, pady=5) self.out_entry = tk.Entry(container) self.out_entry.grid(column=1, row=2, sticky='new', padx=1, pady=5) self.button = tk.Button(container, text='Calculate', cursor='hand2') self.button.grid(column=0, columnspan=2, row=3, sticky='e', padx=1, pady=4) class Controller: ''' Controller class handles communication between the window and action classes ''' def __init__(self, action, window): self.action = action self.window = window # Set the command for the window button self.window.button['command'] = self.calculate def calculate(self): ''' Method for calling the calculation function in action class ''' # Grab the entry fields from window class start = self.window.in_entry.get().strip() end = self.window.out_entry.get().strip() # Set and call the calculate method in action class validate = self.action.calculate(start, end) # If entries are valid show total hours else show error if validate: showinfo('Time Calculated', f'Total Hours: {validate}') else: showerror('Error!', 'Please ensure you are entering the correct time format. Uses 24 hour format. An example would be 14:30 = 2:30 pm') if __name__ == '__main__': root = tk.Tk() controller = Controller(Action(), Window(root)) root.mainloop()