Source code for easy_time_tracker.gui
"""
A simple GUI
"""
import tkinter as tk
from tkinter import messagebox
from .easy_time_tracker import EasyTimeTracker
from .constants import EASY_TIME_TRACKER_PROJECT_LIST
from .util.file_read_write import check_if_current_file_exists, read_text_file
[docs]class Gui(tk.Frame): # pylint: disable=too-many-instance-attributes
"""Class to run the Easy Time Tracker GUI
:type master: tk.Tk
:param master: The tkinter object
:rtype: None
:returns: None
"""
start_group = []
stop_group = []
def __init__(self, master: tk.Tk = None) -> None:
super().__init__(master)
self.master = master
self.pack(padx=25, pady=25)
self.start_button = None
self.stop_button = None
self.description_text_box_label = None
self.description_text_box = None
self.comments_text_box_label = None
self.comments_text_box = None
self.people_text_box_label = None
self.people_text_box = None
self.project_dropdown_label = None
self.project_dropdown = None
self.project_dropdown_clicked = None
self.create_description_text_box()
self.create_people_text_box()
if check_if_current_file_exists(EASY_TIME_TRACKER_PROJECT_LIST):
projects = read_text_file(EASY_TIME_TRACKER_PROJECT_LIST).splitlines()
if len(projects) >= 1:
self.create_project_dropdown(projects)
self.create_comments_text_box()
self.create_stop_button()
self.create_start_button()
self.ett_obj = EasyTimeTracker()
[docs] def create_start_button(self) -> None:
"""Method to create the start button and hide the stop group
:rtype: None
:returns: None
"""
self.start_button = tk.Button(self, height=2, width=80, bg='green')
self.start_button['text'] = 'START'
self.start_button['command'] = self.start_button_callback
self.start_button.pack(side='top')
self.start_group.append((self.start_button, 'top'))
self.hide(self.stop_group)
[docs] def create_stop_button(self) -> None:
"""Method to create the stop button
:rtype: None
:returns: None
"""
self.stop_button = tk.Button(self, height=2, width=80, bg='red')
self.stop_button['text'] = 'STOP'
self.stop_button['command'] = self.stop_button_callback
self.stop_button.pack(side='top')
self.stop_group.append((self.stop_button, 'top'))
[docs] def create_description_text_box(self) -> None:
"""Method to create the description text box and label for it
:rtype: None
:returns: None
"""
self.description_text_box_label = tk.Label(self, font=20)
self.description_text_box_label['text'] = 'Description'
self.description_text_box_label.pack(side='bottom')
self.description_text_box = tk.Entry(self, width=120, font=20)
self.description_text_box.pack(side='bottom')
self.start_group.append((self.description_text_box_label, 'bottom'))
self.start_group.append((self.description_text_box, 'bottom'))
[docs] def create_people_text_box(self) -> None:
"""Method to create the people text box and label for it
:rtype: None
:returns: None
"""
self.people_text_box_label = tk.Label(self, font=20)
self.people_text_box_label['text'] = 'People'
self.people_text_box_label.pack(side='bottom')
self.people_text_box = tk.Entry(self, width=120, font=20)
self.people_text_box.pack(side='bottom')
self.start_group.append((self.people_text_box_label, 'bottom'))
self.start_group.append((self.people_text_box, 'bottom'))
[docs] def create_project_dropdown(self, projects: list) -> None:
"""Method to create the project dropdown box
:type projects: list
:param projects: The list of projects
:rtype: None
:returns: None
"""
self.project_dropdown_label = tk.Label(self, font=20)
self.project_dropdown_label['text'] = 'Project'
self.project_dropdown_label.pack(side='bottom')
# datatype of menu text
self.project_dropdown_clicked = tk.StringVar()
# initial menu text
self.project_dropdown_clicked.set('NA')
self.project_dropdown = tk.OptionMenu(self, self.project_dropdown_clicked, *projects)
self.project_dropdown.pack(side='bottom')
self.start_group.append((self.project_dropdown_label, 'bottom'))
self.start_group.append((self.project_dropdown, 'bottom'))
[docs] def create_comments_text_box(self) -> None:
"""Method to create the comments text box and label for it
:rtype: None
:returns: None
"""
self.comments_text_box_label = tk.Label(self, font=20)
self.comments_text_box_label['text'] = 'Comments'
self.comments_text_box_label.pack(side='bottom')
self.comments_text_box = tk.Entry(self, width=120, font=20)
self.comments_text_box.pack(side='bottom')
self.stop_group.append((self.comments_text_box_label, 'bottom'))
self.stop_group.append((self.comments_text_box, 'bottom'))
[docs] def start_button_callback(self) -> None:
"""Method for the callback of a start button click
:rtype: None
:returns: None
"""
if len(self.people_text_box.get()) == 0:
people = []
else:
people = self.people_text_box.get().split(',')
if len(self.description_text_box.get()) > 0:
try:
if self.project_dropdown_clicked.get() != 'NA':
self.ett_obj.start_time_record(description=self.description_text_box.get(), people=people,
project=self.project_dropdown_clicked.get())
else:
self.ett_obj.start_time_record(description=self.description_text_box.get(), people=people)
self.clear_text_box(self.description_text_box)
self.clear_text_box(self.people_text_box)
self.unhide(self.stop_group)
self.hide(self.start_group)
except FileExistsError:
response = messagebox.askquestion(title='RECORD IN PROGRESS',
message='Would you like to end the in progress record?')
if response == 'yes':
self.stop_button_callback()
else:
messagebox.showinfo(title='RECORD IN PROGRESS', message='Record in progress will keep going.')
else:
messagebox.showerror(title='MISSING REQUIRED DATA!!', message='A Description is required!')
[docs] def stop_button_callback(self) -> None:
"""Method for the callback of a stop button click
:rtype: None
:returns: None
"""
self.ett_obj.end_time_record(self.comments_text_box.get())
self.clear_text_box(self.comments_text_box)
self.unhide(self.start_group)
self.hide(self.stop_group)
[docs] @staticmethod
def clear_text_box(text_box: tk.Entry):
"""Static Method to clear a text box
:type text_box: tk.Entry
:param text_box: The text box to clear
:rtype: None
:returns: None
"""
text_box.delete(0, tk.END)
[docs] @staticmethod
def hide(group: list) -> None:
"""Static Method to hide a list of widgets
:rtype: None
:returns: None
"""
for item in group:
item[0].pack_forget()
[docs] @staticmethod
def unhide(group: list) -> None:
"""Static Method to unhide a list of widgets
:rtype: None
:returns: None
"""
for item in group:
item[0].pack(side=item[1])
[docs]def ett_gui() -> None:
"""Function to start the GUI
:rtype: None
:returns: None
"""
root = tk.Tk()
app = Gui(master=root)
app.mainloop()