def modify_page(): sg.theme('DarkBlue') mod_layout = [[sg.Text("Balance:"), sg.InputText()], [sg.Text("Monthly income:"), sg.InputText("Amount")], [sg.Text("Monthly expenses:"), sg.InputText("Amount")], [sg.Text("Next payment date:"), sg.InputText("YYYY-MM-DD")], [sg.Button('Submit'), sg.Button('Cancel')]] window = sg.Window('Expense Tracker', mod_layout) while True: event, values = window.read() if event == sg.WIN_CLOSED or event == "Cancel": # Close window or cancel to exit window.close() home_page() break elif event == "Submit": details[2] = values[0] details[3] = values[1] details[4] = values[2] details[5] = values[3] print(details) mngr = data_manager.Data_manager() mngr.account_details(user_now, details[0], details[1], details[2], details[3], details[4], details[5], add_inc, add_exp) window.close() home_page() break
def home_page(): sg.theme('DarkBlue') #GUI color scheme # Initiate data manager and apply it to the current user global mngr mngr = data_manager.Data_manager() global details details = mngr.get_details(user_now) # Compare the current date to the next payment to get # money per day d1 = details[5] year, month, day = map(int, d1.split('-')) d1 = datetime.date(year, month, day) now = datetime.datetime.now() d0 = datetime.date(now.year, now.month, now.day) delta = d1 - d0 days = delta.days moneyperday = int(details[2]) // days # Main layout main_layout = [ [sg.Text("Balance: "+details[2]+"\u20ac",font=("Helvetica",20)),\ sg.Text("Monthly income: "+details[3]+"\u20ac",font=("Helvetica",20),text_color='green'),\ sg.Text("Monthly expenses: "+details[4]+"\u20ac",font=("Helvetica",20),text_color='red')],\ [sg.Text("Next payment: "+details[5],font=("Helvetica",20),text_color='green')],\ [sg.Text("Money per day: "+str(moneyperday)+"\u20ac",font=("Helvetica",20),text_color='green')], [sg.Button("Modify")], [sg.Text("Single incomes")], [sg.Listbox(values=[i for i in add_inc],size=(20,5))], [sg.Text("Single expenses")], [sg.Listbox(values=[i for i in add_exp],size=(20,5))], [sg.Button("Add single income"),sg.Button("Add single expense")], [sg.Button('Quit')]] # Home window window = sg.Window('Expense Tracker', main_layout, size=(900, 600)) while True: event, values = window.read() if event == sg.WIN_CLOSED or event == 'Quit': # Close window or cancel to exit break elif event == 'Modify': window.close() modify_page() elif event == "Add single income": window.close() modify_income() break elif event == "Add single expense": window.close() modify_expense() break
def compile_html(width, height): data_manager = dm.Data_manager() try: data_manager.load_data() except: pass html_data = HTML_HEADER data_manager.database.sort(key=lambda x: int(x["number"])) for entry in data_manager.database: html_data += HTML_IMAGE.format( entry["number"], entry["name"], entry["picture"], width, height, entry["description"].replace("\n", "<br>")) html_data += HTML_FOOTER f = open("catalog.html", "w") f.write(html_data) f.close()
def account_creation(): sg.theme('DarkBlue') #GUI color scheme # Creation Layout # Asks user for details that will be used in the # main page creation_layout = [[sg.Text('Create an account')], [sg.Text("Username:"******"Password:"******"First name:"), sg.InputText()], [sg.Text("Last name:"), sg.InputText()], [sg.Text("Balance:"), sg.InputText()], [sg.Text("Monthly income:"), sg.InputText("Amount")], [sg.Text("Monthly expenses:"), sg.InputText("Amount")], [ sg.Text("Next payment date:"), sg.InputText("YYYY-MM-DD") ], [sg.Button('Submit'), sg.Button('Cancel')]] # Creation Window window = sg.Window('Expense Tracker', creation_layout) while True: event, values = window.read() if event == sg.WIN_CLOSED: # Close window or cancel to exit window.close() break elif event == 'Cancel': window.close() loginscreen() break elif event == 'Submit': mngr = data_manager.Data_manager() mngr.create_user(values[0], values[1]) mngr.account_details(values[0], values[2], values[3], values[4], values[5], values[6], values[7], [], []) window.close() loginscreen()
def loginscreen(): sg.theme('DarkBlue') #GUI color scheme # Sign in Layout signin_layout = [ [sg.Text('Expense tracker. Create an account or login')], [sg.Text("Username:"******"Password:"******"OK": global user_now user_now = values[0] window.close() home_page() break elif result == "false": print("Uname not found") else: continue elif event == 'Create an account instead': window.close() account_creation() break
def verify_database_call(): data_manager = dm.Data_manager() try: data_manager.load_data() except: pass missing_count = 0 extra_count = 0 duplicate_picture_count = 0 duplicate_number_count = 0 duplicate_name_count = 0 dataset_pictures = [ entry["picture"].split("\\")[1] for entry in data_manager.database ] file_system_pictures = os.listdir("pictures") should_add_skips = data_manager.index >= len(data_manager.database) for file in file_system_pictures: if not file in dataset_pictures: missing_count += 1 if should_add_skips: data_manager.got_skipped.append(file) if should_add_skips: data_manager.save_data() for file in dataset_pictures: if not file in file_system_pictures: extra_count += 1 if dataset_pictures.count(file) > 1: duplicate_picture_count += 1 dataset_numbers = [entry["number"] for entry in data_manager.database] for number in dataset_numbers: if dataset_numbers.count(number) > 1: duplicate_number_count += 1 dataset_names = [entry["name"] for entry in data_manager.database] for name in dataset_names: if dataset_names.count(name) > 1: duplicate_name_count += 1 missing_count_label.configure(text="") missing_count_label.text = "" extra_count_label.configure(text="") extra_count_label.text = "" duplicate_picture_count_label.configure(text="") duplicate_picture_count_label.text = "" duplicate_number_count_label.configure(text="") duplicate_number_count_label.text = "" duplicate_name_count_label.configure(text="") duplicate_name_count_label.text = "" if missing_count: missing_count_label.configure( text= "There are {0} missing pictures from your dataset. Use first pass to correct this" .format(missing_count)) missing_count_label.text = "There are {0} missing pictures from your dataset. Use first pass to correct this".format( missing_count) if extra_count: extra_count_label.configure( text= "There are {0} pictures in your dataset that are no longer in the pictures folder." .format(extra_count)) extra_count_label.text = "There are {0} pictures in your dataset that are no longer in the pictures folder.".format( extra_count) if duplicate_picture_count: duplicate_picture_count_label.configure( text="There are {0} duplicate pictures in your dataset.". format(duplicate_picture_count // 2)) duplicate_picture_count_label.text = "There are {0} duplicate pictures in your dataset.".format( duplicate_picture_count // 2) if duplicate_number_count: duplicate_number_count_label.configure( text= "There are {0} duplicate numbers in your dataset. Honestly this souldn't be possible without modifying savestate.json, please report this as a bug" .format(duplicate_number_count // 2)) duplicate_number_count_label.text = "There are {0} duplicate numbers in your dataset. Honestly this souldn't be possible without modifying savestate.json, please report this as a bug".format( duplicate_number_count // 2) if duplicate_name_count: duplicate_name_count_label.configure( text="There are {0} duplicate names in your dataset.".format( duplicate_name_count // 2)) duplicate_name_count_label.text = "There are {0} duplicate names in your dataset.".format( duplicate_name_count // 2)
def main(old_window=None, return_function=lambda *_: None): if old_window: old_window.destroy() window = tk.Tk() window.state('zoomed') greeting = tk.Label( master=window, text="Fill in the information for the following picture:") greeting.pack() frame = tk.Frame(master=window, borderwidth=5) frame.pack() data_manager = dm.Data_manager() try: data_manager.load_data() except: pass name_frame = tk.Frame(master=frame, borderwidth=5) name_frame.pack(side=tk.LEFT) name_label = tk.Label(master=name_frame, text="Name:") name_entry = tk.Entry(master=name_frame, width=50) name_label.pack() name_entry.pack() number_frame = tk.Frame(master=frame, borderwidth=5) number_frame.pack(side=tk.LEFT) number_label = tk.Label(master=number_frame, text="Number:") number_entry = tk.Entry(master=number_frame, width=20) number_label.pack() number_entry.pack() picture_frame = tk.Frame(master=frame, borderwidth=5) picture_frame.pack(side=tk.LEFT) try: img = os.path.join("pictures", data_manager.get_next_picture()) except EOFError: id.info_dialogue("No images remain, redirecting to catalog creator", hc.main, old_window=window, return_function=return_function) return load = Image.open(img) load = load.resize((250, 250), Image.ANTIALIAS) render = ImageTk.PhotoImage(load) picture_label_text = tk.Label(master=picture_frame, text=img) picture_label = tk.Label(master=picture_frame, image=render) picture_label_text.pack() picture_label.pack() description_frame = tk.Frame(master=frame, borderwidth=5) description_frame.pack(side=tk.LEFT) description_label = tk.Label(master=description_frame, text="Description:") description_entry = tk.Text(master=description_frame, width=100) description_label.pack() description_entry.pack() error_label = tk.Label(master=window, text="", fg="red") error_label.pack() def submit_call(): nonlocal img data = {} data["name"] = name_entry.get() data["number"] = number_entry.get() data["description"] = description_entry.get("1.0", tk.END) data["picture"] = img errors = check_errors(data) error_label.configure(text=errors) error_label.text = errors if errors: return data_manager.collect_data(data) data_manager.save_data() name_entry.delete(0, tk.END) number_entry.delete(0, tk.END) description_entry.delete("1.0", tk.END) try: new_img = os.path.join("pictures", data_manager.get_next_picture()) except EOFError: id.info_dialogue( "No images remain, redirecting to catalog creator", hc.main, old_window=window, return_function=return_function) return load = Image.open(new_img) load = load.resize((250, 250), Image.ANTIALIAS) render = ImageTk.PhotoImage(load) picture_label.configure(image=render) picture_label.image = render picture_label_text.configure(text=new_img) picture_label_text.text = new_img img = new_img def check_errors(data): if not data["name"]: return "Please provide a name for the picture." if not data["number"] or not data["number"].isnumeric() or int( data["number"]) < 1: return "Please provide a valid number for the picture." dataset_numbers = [entry["number"] for entry in data_manager.database] if data["number"] in dataset_numbers: return "A picture in the dataset already uses this number." if not data["description"] or data["description"] == "\n": return "Please provide a description for the picture." if not data["picture"]: return "Something went wrong with the picture. Please restart the program." return "" button = tk.Button(master=window, command=submit_call, text="Save and load next picture") button.pack() def main_menu_call(): nonlocal window cd.confirm_dialogue("Return to main menu and discard unsaved changes?", return_function, window) main_menu_frame = tk.Frame(master=window, borderwidth=50) main_menu_frame.pack() main_menu_button = tk.Button(master=main_menu_frame, command=main_menu_call, text="Main menu") main_menu_button.pack() window.mainloop()
def main(old_window=None, return_function=lambda *_: None): if old_window: old_window.destroy() window = tk.Tk() screen_width = window.winfo_screenwidth() screen_height = window.winfo_screenheight() window.geometry("{0}x{1}+{2}+{3}".format(screen_width//2, screen_height//2, screen_width//2 - screen_width//4, screen_height//2 - screen_height//4)) data_manager = dm.Data_manager() try: data_manager.load_data() except: pass greeting = tk.Label(master=window, text="Edit an entry:") greeting.pack() frame = tk.Frame(master=window, borderwidth=50) frame.pack() number_frame = tk.Frame(master=frame, borderwidth=5) number_frame.pack(side=tk.LEFT) number_label = tk.Label(master=number_frame, text="Number of the entry to be edited:") number_entry = tk.Entry(master=number_frame, width=20) number_label.pack() number_entry.pack() error_label = tk.Label(master=window, text="", fg="red") error_label.pack() def edit_call(): number = number_entry.get() errors = check_errors(number) error_label.configure(text=errors) error_label.text = errors if errors: return ep.main(old_window=window, return_function=return_function, continue_function=main, number=number) pass def check_errors(data): if not data or int(data) < 1: return "Please provide a valid number to fetch." dataset_numbers = [entry["number"] for entry in data_manager.database] if not data in dataset_numbers: return "That entry does not exist." return "" button1 = tk.Button(master=frame, command=edit_call, text="edit") button1.pack(side=tk.LEFT) error_label = tk.Label(master=window, text="", fg="red") error_label.pack() def main_menu_call(): nonlocal window cd.confirm_dialogue("Return to main menu?", return_function, window) main_menu_button = tk.Button(master=window, command=main_menu_call, text="Main menu") main_menu_button.pack() window.mainloop()