예제 #1
0
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller = controller
        self.parent = parent

        global back_img, create_img, buttonbg

        back_img = ImageTk.PhotoImage(Image.open("assets/back.png"))
        back_btn = Button(self,
                          text="Back to Menu",
                          image=back_img,
                          anchor="center",
                          compound="left",
                          bd=0,
                          padx=-10,
                          command=lambda: controller.show_frame("Homescreen"))
        back_btn.pack(pady=(0, 20))

        image = Label(self,
                      image=diary_img,
                      text="Diary",
                      compound="left",
                      padx=10)
        image.pack()

        diary_help = Label(
            self,
            text=
            "Use the diary to store your thoughts or narrate how your day went.\nDon't worry, Andy is great at keeping secrets ;]"
        )
        diary_help.pack(pady=10)

        create_img = ImageTk.PhotoImage(
            Image.open("assets/create.png").resize((30, 30), Image.ANTIALIAS))
        create_btn = Button(
            self,
            text="Create new entry",
            image=create_img,
            anchor="center",
            compound="left",
            bd=0,
            command=lambda: controller.show_frame("DiaryCreateFrame"))
        create_btn.pack(pady=(10, 20))

        cal = Calendar(self,
                       firstweekday="sunday",
                       showweeknumbers=False,
                       borderwidth=0,
                       date_pattern="yyyy-mm-dd")
        cal.pack(padx=20, pady=10)
        buttonbg = ImageTk.PhotoImage(
            Image.open("assets/create.png").resize((30, 30), Image.ANTIALIAS))
        print_btn = Button(self,
                           cursor="dotbox",
                           text="Check Entries for the selected date",
                           image=buttonbg,
                           bd=0,
                           command=lambda: self.check_records(cal.get_date()))
        print_btn.pack(padx=15, pady=15)
class MyCalendar(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        #Create calendar
        self.cal = Calendar(self,
                            font="Arial 14",
                            selectmode='day',
                            tooltipforeground='black',
                            tooltipbackground='pink',
                            tooltipalpha='1',
                            tooltipdelay='0')
        date = self.cal.datetime.today()

        #Add in events
        self.cal.c1 = self.cal.calevent_create(
            date + self.cal.timedelta(days=5), "F**k me in the ass", 'message')
        self.cal.calevent_create(date, 'Bake cookies at 3am', 'reminder')
        self.cal.calevent_create(date + self.cal.timedelta(days=-2),
                                 'Date at McDonalds', 'reminder')
        self.cal.calevent_create(date + self.cal.timedelta(days=3),
                                 'Mine Diamonds with Jimothy', 'message')

        #Set calendar and adjust colours
        self.cal.tag_config('reminder', background='red', foreground='yellow')
        self.cal.pack(fill="both", expand=True)

        #Set status/tool tip bar
        self.l2 = tk.Label(self,
                           text="Click on a date to check for events!",
                           width=40)
        self.l2.pack(side="bottom")

        #Executes "set_date" when a day is clicked
        self.cal.bind("<<CalendarSelected>>", self.set_date)

    def set_date(self, event):

        #Get the date clicked
        self.date = self.cal.get_date()

        #Convert date from string format to datetime object format
        self.DTObject = datetime.strptime(self.date, '%m/%d/%y')

        #Get tuple of events on the date clicked
        self.eventslist = self.cal.get_calevents(self.DTObject)

        #If there >0 events, display first event on status/tool tip bar
        if len(self.eventslist) > 0:
            self.l2.configure(
                text=self.cal.calevents[self.eventslist[0]]["text"])

        #Display no events
        else:
            self.l2.configure(text="No events for " + self.date)
예제 #3
0
class AUView(tk.Toplevel):
    def __init__(self, parent_view):
        super().__init__(parent_view)
        self.parent = parent_view
        self.title('AU/krank Eintragen')
        startdatum_label = tk.Label(self, text="von")
        self.startdatum_input = Calendar(self, date_pattern='MM/dd/yyyy')
        enddatum_label = tk.Label(self, text="bis")
        self.enddatum_input = Calendar(self, date_pattern='MM/dd/yyyy')

        self.save_button = tk.Button(self, text="Daten speichern")
        self.exit_button = tk.Button(self,
                                     text="Abbrechen",
                                     command=self.destroy)
        self.saveandnew_button = tk.Button(self,
                                           text="Daten speichern und neu")

        # ins Fenster packen
        startdatum_label.grid(row=1, column=0, sticky=tk.NW)
        self.startdatum_input.grid(row=1, column=1, columnspan=2, sticky=tk.NW)
        enddatum_label.grid(row=1, column=3, sticky=tk.NW)
        self.enddatum_input.grid(row=1, column=4, sticky=tk.NW)

        self.save_button.grid(row=15, column=0, sticky=tk.NW)
        self.exit_button.grid(row=15, column=1, sticky=tk.NW)
        self.saveandnew_button.grid(row=15, column=2, sticky=tk.NW)

    def set_data(self, **kwargs):
        self.startdatum_input.selection_set(kwargs['beginn'])
        self.enddatum_input.selection_set(kwargs['ende'])

    def get_data(self):
        startdatum_date_obj = datetime.strptime(
            self.startdatum_input.get_date(), '%m/%d/%Y')
        enddatum_date_obj = datetime.strptime(self.enddatum_input.get_date(),
                                              '%m/%d/%Y')

        return {'beginn': startdatum_date_obj, 'ende': enddatum_date_obj}
예제 #4
0
    def test_calendar_textvariable(self):
        var = tk.StringVar(self.window)
        widget = Calendar(self.window,
                          selectmode='day',
                          year=2015,
                          month=1,
                          day=3,
                          textvariable=var)
        widget.pack()
        self.window.update()
        self.assertEqual('', var.get())
        self.assertEqual('', widget.get_date())
        self.assertEqual(date(2015, 1, 1), widget._date)
        widget.selection_set(date(2018, 11, 21))
        self.window.update()
        self.assertEqual(format_date(date(2018, 11, 21), 'short'), var.get())
        self.assertEqual(format_date(date(2018, 11, 21), 'short'),
                         widget.get_date())
        widget.selection_set(None)
        self.window.update()
        self.assertEqual('', widget.get_date())
        self.assertEqual('', var.get())
        var.set(format_date(date(2014, 3, 2), 'short'))
        self.window.update()
        self.assertEqual(date(2014, 3, 2), widget.selection_get())
        self.assertEqual(format_date(date(2014, 3, 2), 'short'), var.get())
        self.assertEqual(format_date(date(2014, 3, 2), 'short'),
                         widget.get_date())
        try:
            var.set('a')
        except tk.TclError:
            # some versions of python raise an error because of the exception
            # raised inside the trace
            pass
        self.window.update()
        self.assertEqual(date(2014, 3, 2), widget.selection_get())
        self.assertEqual(format_date(date(2014, 3, 2), 'short'), var.get())
        self.assertEqual(format_date(date(2014, 3, 2), 'short'),
                         widget.get_date())
        var.set('')
        self.window.update()
        self.assertIsNone(widget.selection_get())
        self.assertEqual('', var.get())
        self.assertEqual('', widget.get_date())

        var2 = tk.StringVar(widget, format_date(date(2011, 1, 21), 'short'))
        widget['textvariable'] = var2
        self.window.update()
        self.assertEqual(widget.get_date(), var2.get())
        self.assertEqual('', var.get())
예제 #5
0
class Datetime:
    def __init__(self, master, label):
        self.master = master
        self.frame = tk.Frame(self.master)
        self.frame.config(bg="white")
        self.cal = Calendar(self.frame,
                            select="day",
                            year=2021,
                            month=2,
                            day=9)
        self.cal.grid(row=0, column=0, padx=20, pady=20)
        self.time = App(self.frame)
        self.time.grid(row=1, column=0, padx=10, pady=10)
        self.label = label

        # -----------Buttons-----------

        # Select datetime button
        self.pickDateButton = tk.Button(self.frame,
                                        text="Seleccionar fecha y hora",
                                        command=self.grab_date)
        self.pickDateButton.grid(row=2, column=0, pady=20, padx=20)

        # Exit button
        self.quitButton = tk.Button(self.frame,
                                    text='Salir',
                                    width=25,
                                    command=self.close_windows)
        self.quitButton.grid(row=3, column=0, padx=20, pady=20)

        self.frame.pack()

    # Prints chosed date into parent window (NewRecordDate)
    def grab_date(self):
        chosedDatetime = self.cal.get_date() + " " + self.time.hourstr.get(
        ) + ":" + self.time.minstr.get()
        self.label.config(text=chosedDatetime)

    # Destroys current window
    def close_windows(self):
        self.master.destroy()
예제 #6
0
 def test_calendar_textvariable(self):
     var = tk.StringVar(self.window,)
     widget = Calendar(self.window, selectmode='day', locale=None,
                       year=2015, month=1, day=3, textvariable=var)
     widget.pack()
     self.window.update()
     self.assertEqual(datetime(2015, 1, 3).strftime('%x'), var.get())
     self.assertEqual(datetime(2015, 1, 3).strftime('%x'), widget.get_date())
     widget.selection_set(datetime(2018, 11, 21))
     self.window.update()
     self.assertEqual(datetime(2018, 11, 21).strftime('%x'), var.get())
     self.assertEqual(datetime(2018, 11, 21).strftime('%x'), widget.get_date())
     widget.selection_set(None)
     self.window.update()
     self.assertEqual('', widget.get_date())
     self.assertEqual('', var.get())
     var.set(datetime(2014, 3, 2).strftime('%x'))
     self.window.update()
     self.assertEqual(datetime(2014, 3, 2), widget.selection_get())
     self.assertEqual(datetime(2014, 3, 2).strftime('%x'), var.get())
     self.assertEqual(datetime(2014, 3, 2).strftime('%x'), widget.get_date())
     try:
         var.set('a')
     except tk.TclError:
         # some versions of python raise an error because of the exception
         # raised inside the trace
         pass
     self.window.update()
     self.assertEqual(datetime(2014, 3, 2), widget.selection_get())
     self.assertEqual(datetime(2014, 3, 2).strftime('%x'), var.get())
     self.assertEqual(datetime(2014, 3, 2).strftime('%x'), widget.get_date())
     var.set('')
     self.window.update()
     self.assertIsNone(widget.selection_get())
     self.assertEqual('', var.get())
     self.assertEqual('', widget.get_date())
예제 #7
0
class GUI:

    #desc: constructor, initializes the relevant variables, buttons, canvas, frame, ect
    def __init__(self):
        self.day_one = "5/8/16"  #index 881 of processed data
        self.date_one = datetime.datetime(day=5, month=8, year=2016)
        self.states = {"testing": False, "tested": False}  #state of the gui
        self.root = tk.Tk()
        self.height = 500
        self.width = 1000

        self.canvas = tk.Canvas(self.root,
                                height=self.height,
                                width=self.width,
                                bg="#263d42")
        self.canvas.pack()

        self.frame = tk.Frame(self.root, bg="#3e646c")

        self.frame.place(width=self.width * 0.6, height=self.height, y=0, x=0)

        self.btns = {}
        self.labels = {}

        self.test_list = []

        self.btns["run"] = Button(self.frame,
                                  text="Play Trading Period",
                                  fg="#263d42")
        self.btns["run"].grid(row=0)
        self.btns["run"].bind("<Button-1>", self.run_test)

        self.btns["graph"] = Button(self.frame,
                                    text="Create Graph",
                                    fg="#263d42")
        self.btns["graph"].grid(row=0, column=1)
        self.btns["graph"].bind("<Button-1>", self.update_chart)

        self.btns["alloc"] = Button(self.frame,
                                    text="Show Allocations",
                                    fg="#263d42")
        self.btns["alloc"].grid(row=0, column=2)
        self.btns["alloc"].bind("<Button-1>", self.show_allocations)

        self.btns["roi"] = Button(self.frame, text="Show ROI", fg="#263d42")
        self.btns["roi"].grid(row=0, column=3)
        self.btns["roi"].bind("<Button-1>", self.show_roi)

        self.labels["run"] = Label(self.frame, text="Not Running")

        self.cal = Calendar(self.canvas,
                            font="Arial 14",
                            selectmode='day',
                            cursor="hand1",
                            year=2018,
                            month=2,
                            day=5)

        self.cal.pack(fill="both", expand=True)
        self.canvas.create_window((self.width * 0.6, 0),
                                  window=self.cal,
                                  anchor='nw')

    #desc: runs the test version of the trader, collects the trading data
    def run_test(self, event):
        print("running test")
        self.states["testing"] = True
        self.market = Market_Environment("processed stock data")
        self.test_list = trader.run_test(self.market)
        self.states["testing"] = False
        self.states["tested"] = True

    #desc: shows the chart of portfolio values against the trading days
    def update_chart(self, event):
        data = []
        for item in self.test_list:
            data.append(item["value"])

        plt.plot(data)
        plt.show()

    #desc: shows a pie chart of stock allocations on a given day
    def show_allocations(self, event):

        if self.states["tested"]:
            day = self.calc_day(self.cal.get_date())  #days is an index

            if -1 < day and day < 378:
                allocations = self.test_list[day]["allocation"]

                total_value = 0
                for stock, amt in allocations.items():
                    if stock in self.test_list[day]["prices"]:
                        total_value += amt * self.test_list[day]["prices"][
                            stock]

                stocks = []
                amounts = []
                for stock, amt in allocations.items():
                    if 0 < amt:
                        amounts.append(amt / total_value)
                        stocks.append(stock)

                labels = stocks

                fig = plt.figure()
                ax = fig.add_axes([0, 0, 1, 1])
                ax.axis('equal')
                ax.pie(amounts, labels=labels, autopct='%1.1f%%')
                plt.show()

    #desc: shows the roi of the portfolio
    def show_roi(self, event):
        if self.states["tested"]:
            roi = (self.test_list[364]["value"] -
                   self.test_list[0]["value"]) / self.test_list[0]["value"]
            roi *= 100
            self.labels["roi"] = Label(self.frame,
                                       text="Yearly roi: " + str(roi))
            self.labels["roi"].grid(row=1, column=3)

    #desc: runs the gui loop
    def run_gui(self):
        self.root.mainloop()

    #desc: gives index based on difference between first day and choosen
    #input: date - the trading date as a mm/dd/yy string
    def calc_day(self, date):
        value_p = re.compile(r'\d+')
        (month, day, year) = value_p.findall(date)
        (day, month, year) = (int(day), int(month), int(year) + 2000)
        date = datetime.datetime(day=day, month=month, year=year)
        index = (date - self.date_one).days
        return index
예제 #8
0
파일: gui.py 프로젝트: SLusenti/doit
class app(Tk):
    def __init__(self,
                 screenName=None,
                 baseName=None,
                 className="Doit!",
                 useTk=1,
                 sync=0,
                 use=None):
        super().__init__(screenName=screenName,
                         baseName=baseName,
                         className=className,
                         useTk=useTk,
                         sync=sync,
                         use=use)
        self.tcont = TaskContainer()
        self.new_description = ""
        self.protocol("WM_DELETE_WINDOW", self.quit_event)
        icon_src = os.path.dirname(os.path.realpath(__file__)) + '/doit.png'
        self.tk.call('wm', 'iconphoto', self._w, PhotoImage(file=icon_src))
        #self.tcont.today = datetime.date.today() - datetime.timedelta(day=1) # uncomment only for debugging/testing purpose
        self.current_task = None
        self.task_list_old = []
        self.task_list_wip = []
        self.task_list_day = []
        self.drow_menu_frame()
        self.drow_panel()
        self.drow_list()
        self.drow_task_frame()
        self.drow_reschedule_frame()
        self.drow_new_task_frame()
        self.drow_complete_frame()

        if len(self.tcont.task_list) > 0:
            self.fetch_list()
            if len(self.tcont.day_tasks_list) > 0:
                self.update_task_frame()
                self.task_frame.pack(fill=BOTH, expand=True)

        if len(self.tcont.old_list) > 0:
            self.fetch_old()

        self.tcont.export_db("./snapshot_db.json")

    def drow_menu_frame(self):
        def import_fn():
            self.tcont.export_db("./snapshot_db.json")
            self.tcont.import_db()
            self.fetch_list_event()
            self.update_task_frame()
            self.task_frame.pack(fill=BOTH, expand=True)

        menu_frame = Frame(self, bg="gray")
        button_frame = Frame(menu_frame, bg="gray")
        Button(button_frame, text="new task",
               command=self.new_event).pack(side=LEFT, padx=5, pady=5)
        Button(button_frame, text="save",
               command=self.save_event).pack(side=LEFT, padx=5, pady=5)
        Button(button_frame, text="export",
               command=self.tcont.export_db).pack(side=LEFT, padx=5, pady=5)
        Button(button_frame, text="import", command=import_fn).pack(side=LEFT,
                                                                    padx=5,
                                                                    pady=5)
        button_frame.pack(side=LEFT, padx=20)

        filter_frame = Frame(menu_frame, bg="gray")
        Label(filter_frame,
              text="Filter:",
              font="LiberationMono-Bold 10",
              bg="gray").pack(side=LEFT, padx=5, pady=5)
        self.filter_mod_string = StringVar()
        self.filter_mod_string.set("")
        ttk.Combobox(filter_frame,
                     justify=RIGHT,
                     textvariable=self.filter_mod_string,
                     values=[mod for mod in filtask.map_filter.keys()],
                     state="readonly").pack(side=LEFT, padx=5, pady=5)
        self.filter_text_string = StringVar()
        self.filter_text_string.set("")
        filter_entry = Entry(filter_frame,
                             width=70,
                             textvariable=self.filter_text_string,
                             font="LiberationMono-Bold 10")
        filter_entry.bind("<Return>", self.fetch_list_event)
        filter_entry.pack(side=LEFT, padx=5, pady=5)
        filter_frame.pack(side=RIGHT, padx=40)

        menu_frame.pack(fill=X)

    def drow_panel(self):
        self.pw = ttk.PanedWindow(self, orient=HORIZONTAL)
        self.pw.pack(fill=BOTH, expand=True)
        self.list_frame = ttk.Frame(self.pw,
                                    width=150,
                                    height=300,
                                    relief=SUNKEN)
        self.main_frame = ttk.Frame(self.pw,
                                    width=150,
                                    height=300,
                                    relief=SUNKEN)
        self.pw.add(self.list_frame, weight=1)
        self.pw.add(self.main_frame, weight=6)

    def drow_complete_frame(self):
        self.complete_frame = ttk.Frame(self.main_frame)

        self.title_complete_string = StringVar()
        self.title_complete_string.set("Completing task: {}")
        title_complete_label = Entry(self.complete_frame,
                                     textvariable=self.title_complete_string,
                                     font="Keraleeyam-Regular 16 bold",
                                     bd=0,
                                     state="readonly",
                                     justify=CENTER)

        comment_label = Label(self.complete_frame,
                              text="Comment",
                              font="LiberationMono-Bold 10")
        self.complete_text = Text(self.complete_frame,
                                  height=10,
                                  font="FreeMono 10")

        cancel_button = ttk.Button(self.complete_frame,
                                   text="cancel",
                                   command=self.cancel_event)
        complete_button = ttk.Button(self.complete_frame,
                                     text="Complete",
                                     command=self.complete_task_event)

        title_complete_label.pack(fill=BOTH, padx=10, pady=15)
        comment_label.pack(fill=BOTH, padx=10)
        self.complete_text.pack(pady=5, fill=X)

        complete_button.pack(side=RIGHT, pady=10)
        cancel_button.pack(side=RIGHT, pady=10, padx=40)

    def drow_reschedule_frame(self):
        self.reschedule_frame = ttk.Frame(self.main_frame)

        self.title_reschedule_string = StringVar()
        self.title_reschedule_string.set("Reschedule task: {}")
        title_reschedule_label = Entry(
            self.reschedule_frame,
            textvariable=self.title_reschedule_string,
            font="Keraleeyam-Regular 16 bold",
            bd=0,
            state="readonly",
            justify=CENTER)

        activity_label = Label(self.reschedule_frame,
                               text="Description of the WIP",
                               font="LiberationMono-Bold 10")
        self.reschedule_text = Text(self.reschedule_frame,
                                    height=10,
                                    font="FreeMono 10")

        calendar_frame = ttk.Frame(self.reschedule_frame)
        calendar_frame.grid_rowconfigure(0, weight=1)
        calendar_frame.grid_columnconfigure(0, weight=1)

        tomorrow = datetime.date.today() + datetime.timedelta(days=1)
        calendar_label = Label(calendar_frame,
                               text="reschedule date",
                               font="LiberationMono-Bold 10")
        self.calendar = Calendar(calendar_frame,
                                 date_pattern="y-mm-dd",
                                 font="Arial 8",
                                 selectmode='day',
                                 cursor="hand1",
                                 year=tomorrow.year,
                                 month=tomorrow.month,
                                 day=tomorrow.day)
        hour_label = Label(calendar_frame,
                           text="expeted time to spend next next",
                           font="LiberationMono-Bold 10")
        self.hour_string = StringVar()
        hour_box = Spinbox(calendar_frame,
                           width=3,
                           from_=1,
                           to=36,
                           textvariable=self.hour_string,
                           command=self.update_label_reschedule_time)
        hour_box.bind("<Return>", self.update_label_reschedule_time)
        self.hour_label = Label(calendar_frame,
                                text="0h 10m",
                                font="LiberationMono-Bold 10")
        hour_eff_label = Label(calendar_frame,
                               text="time spent today",
                               font="LiberationMono-Bold 10")
        self.hour_effective_string = StringVar()
        hour_eff_box = Spinbox(calendar_frame,
                               width=3,
                               from_=1,
                               to=144,
                               textvariable=self.hour_effective_string,
                               command=self.update_label_reschedule_eff_time)
        hour_eff_box.bind("<Return>", self.update_label_reschedule_eff_time)
        self.hour_eff_label = Label(calendar_frame,
                                    text="0h 10m",
                                    font="LiberationMono-Bold 10")
        self.stick = IntVar()
        stick_box = Checkbutton(calendar_frame,
                                text="do not postpone",
                                font="LiberationMono-Bold 10",
                                variable=self.stick)

        calendar_label.grid(column=0, row=0)
        self.calendar.grid(column=0, row=1, rowspan=2)
        hour_eff_label.grid(column=1, row=1, padx=50)
        hour_eff_box.grid(column=2, row=1)
        self.hour_eff_label.grid(column=3, row=1, padx=5)
        hour_label.grid(column=1, row=2, padx=50)
        hour_box.grid(column=2, row=2)
        self.hour_label.grid(column=3, row=2, padx=5)
        stick_box.grid(column=0, row=3, pady=5)

        cancel_button = ttk.Button(self.reschedule_frame,
                                   text="cancel",
                                   command=self.cancel_event)
        reschedule_button = ttk.Button(self.reschedule_frame,
                                       text="Reschedule",
                                       command=self.reschedule_task_event)

        title_reschedule_label.pack(pady=15, fill=X)
        activity_label.pack()
        self.reschedule_text.pack(pady=5, fill=X)
        calendar_frame.pack()
        reschedule_button.pack(side=RIGHT, pady=10)
        cancel_button.pack(side=RIGHT, pady=10, padx=40)

    def drow_new_task_frame(self):
        self.new_task_frame = ttk.Frame(self.main_frame)
        title_label = Label(self.new_task_frame,
                            text="New Task",
                            font="Keraleeyam-Regular 16 bold")

        container_frame = ttk.Frame(self.new_task_frame)
        container_frame.grid_rowconfigure(0, weight=1)
        container_frame.grid_columnconfigure(0, weight=1)
        name_label = Label(container_frame,
                           text="task name",
                           font="LiberationMono-Bold 10")
        self.name_new_task_string = StringVar()
        self.name_new_task_string.set("")
        name_new_task_entry = Entry(container_frame,
                                    textvariable=self.name_new_task_string,
                                    font="Keraleeyam-Regular 10")

        tags_frame = ttk.Frame(self.new_task_frame)
        tags_label = Label(tags_frame,
                           text="tags",
                           font="LiberationMono-Bold 10")
        self.tags_new_task_string = StringVar()
        self.tags_new_task_string.set("")
        tags_new_task_entry = Entry(tags_frame,
                                    textvariable=self.tags_new_task_string,
                                    font="Keraleeyam-Regular 10")
        tags_new_task_entry.bind("<Return>", self.add_new_tag)
        self.tags_container = ttk.Frame(tags_frame)
        tags_label.grid(column=0, row=0)
        tags_new_task_entry.grid(column=1, row=0)
        self.tags_container.grid(column=2, row=0)

        description_new_label = Label(container_frame,
                                      text="Description",
                                      font="LiberationMono-Bold 10")
        self.description_new_text = Text(container_frame, font="FreeMono 10")

        calendar_frame = ttk.Frame(container_frame)
        calendar_frame.grid_rowconfigure(0, weight=1)
        calendar_frame.grid_columnconfigure(0, weight=1)

        day = datetime.date.today()
        calendar_start_label = Label(calendar_frame,
                                     text="start date",
                                     font="LiberationMono-Bold 10")
        self.calendar_start = Calendar(calendar_frame,
                                       date_pattern="y-mm-dd",
                                       font="Arial 8",
                                       selectmode='day',
                                       cursor="hand1",
                                       year=day.year,
                                       month=day.month,
                                       day=day.day)
        calendar_end_label = Label(calendar_frame,
                                   text="due date",
                                   font="LiberationMono-Bold 10")
        self.calendar_due = Calendar(calendar_frame,
                                     date_pattern="y-mm-dd",
                                     font="Arial 8",
                                     selectmode='day',
                                     cursor="hand1",
                                     year=day.year,
                                     month=day.month,
                                     day=day.day)
        self.stick_new = IntVar()
        stick_box = Checkbutton(calendar_frame,
                                text="do not postpone",
                                font="LiberationMono-Bold 10",
                                variable=self.stick_new)

        calendar_start_label.grid(column=0, row=0, pady=5)
        self.calendar_start.grid(column=0, row=1, pady=5)
        calendar_end_label.grid(column=0, row=2, pady=5)
        self.calendar_due.grid(column=0, row=3, pady=5)
        stick_box.grid(column=0, row=4, pady=5)

        name_label.grid(column=0, row=0, padx=15)
        name_new_task_entry.grid(column=0, row=1, padx=15, stick=N + E + S + W)
        description_new_label.grid(column=0, row=2, padx=15)
        self.description_new_text.grid(column=0,
                                       row=3,
                                       stick=N + E + S + W,
                                       padx=15)
        calendar_frame.grid(column=1, row=0, rowspan=5, padx=15)

        label_frame = ttk.Frame(self.new_task_frame)
        label_frame.grid_rowconfigure(0, weight=1)
        label_frame.grid_columnconfigure(0, weight=1)

        hour_label = Label(label_frame,
                           text="Time to spend next",
                           font="LiberationMono-Bold 10")
        self.hour_new_string = StringVar()
        hour_box = Spinbox(label_frame,
                           width=3,
                           from_=1,
                           to=36,
                           textvariable=self.hour_new_string,
                           command=self.update_label_new_time)
        hour_box.bind("<Return>", self.update_label_new_time)
        self.hour_new_label = Label(label_frame,
                                    text="0h 10m",
                                    font="LiberationMono-Bold 10")
        priority_new_label = Label(label_frame,
                                   text="priority 1-5 (1 is the highest)",
                                   font="LiberationMono-Bold 10")
        self.priority_new_string = StringVar()
        priority_new_box = Spinbox(label_frame,
                                   width=3,
                                   from_=1,
                                   to=5,
                                   textvariable=self.priority_new_string)

        hour_label.grid(column=0, row=0, pady=5)
        hour_box.grid(column=1, row=0, pady=5)
        self.hour_new_label.grid(column=2, row=0, pady=5)
        priority_new_label.grid(column=0, row=1, pady=5)
        priority_new_box.grid(column=1, row=1, pady=5)

        cancel_button = ttk.Button(self.new_task_frame,
                                   text="cancel",
                                   command=self.cancel_event)
        create_button = ttk.Button(self.new_task_frame,
                                   text="create",
                                   command=self.new_task_event)

        title_label.pack(pady=15, fill=X)
        container_frame.pack(fill=X, expand=True)
        tags_frame.pack(padx=30, pady=10, fill=X)
        label_frame.pack(pady=5, padx=30)
        create_button.pack(side=RIGHT, pady=10)
        cancel_button.pack(side=RIGHT, pady=10, padx=40)

    def drow_task_frame(self):
        self.task_frame = ttk.Frame(self.main_frame)
        self.title_string = StringVar()
        self.title_string.set("Empty")
        title_label = Entry(self.task_frame,
                            textvariable=self.title_string,
                            font="Keraleeyam-Regular 16 bold",
                            bd=0,
                            state="readonly",
                            justify=CENTER)
        self.id_string = StringVar()
        self.id_string.set("id")
        id_label = Entry(self.task_frame,
                         textvariable=self.id_string,
                         font="FreeMono 10",
                         bd=0,
                         state="readonly",
                         justify=CENTER)

        ldabel_text_frame = Frame(self.task_frame)
        self.label_created = Label(ldabel_text_frame,
                                   text="created: {}",
                                   font="LiberationMono-Bold 10")
        self.label_due = Label(ldabel_text_frame,
                               text="due date: {}",
                               font="LiberationMono-Bold 10")
        self.label_state = Label(ldabel_text_frame,
                                 text="state: {}",
                                 font="LiberationMono-Bold 10")
        self.label_priority = Label(ldabel_text_frame,
                                    text="priority: {}",
                                    font="LiberationMono-Bold 10")
        self.label_time = Label(ldabel_text_frame,
                                text="time to spend next: {}",
                                font="LiberationMono-Bold 10")
        self.label_created.grid(column=0, row=0, padx=20)
        self.label_due.grid(column=1, row=0, padx=20)
        self.label_state.grid(column=2, row=0, padx=20)
        self.label_priority.grid(column=3, row=0, padx=20)
        self.label_time.grid(column=4, row=0, padx=20)

        tags_frame = ttk.Frame(self.task_frame)
        tags_label = Label(tags_frame,
                           text="tags: ",
                           font="LiberationMono-Bold 10")
        self.tags_task_string = StringVar()
        self.tags_task_string.set("")
        self.tags_task_entry = Entry(tags_frame,
                                     textvariable=self.tags_task_string,
                                     font="Keraleeyam-Regular 10")
        self.tags_task_entry.bind("<Return>", self.add_task_tag)
        self.tags_frame = ttk.Frame(tags_frame)
        self.tags_frame.bind("<Leave>", self.save_tags)
        tags_label.grid(column=0, row=0)
        self.tags_task_entry.grid(column=1, row=0)
        self.tags_frame.grid(column=2, row=0)

        main_task_frame = ttk.Frame(self.task_frame)
        tabs = ttk.Notebook(main_task_frame)

        def myfunction(event):
            canvas.configure(scrollregion=canvas.bbox("all"))

        def onCanvasConfigure(event):
            canvas.itemconfigure(canvas_item, width=canvas.winfo_width() - 20)

        activity_frame = ttk.Frame(tabs)
        canvas = Canvas(activity_frame, width=20, height=20)
        self.activity_frame_main = Frame(canvas)
        scroll1 = Scrollbar(activity_frame,
                            orient=VERTICAL,
                            command=canvas.yview)
        canvas.config(yscrollcommand=scroll1.set)
        canvas_item = canvas.create_window((0, 0),
                                           window=self.activity_frame_main,
                                           anchor='w')
        self.activity_frame_main.bind("<Configure>", myfunction)
        canvas.bind('<Configure>', onCanvasConfigure)
        canvas.pack(side=LEFT, fill=BOTH, expand=True)
        scroll1.pack(side=RIGHT, fill=Y)

        def myfunction2(event):
            canvas_rel.configure(scrollregion=canvas_rel.bbox("all"))

        def onCanvasConfigure2(event):
            canvas_rel.itemconfigure(canvas_rel_item,
                                     width=canvas_rel.winfo_width() - 20)

        relation_frame = Frame(tabs)
        canvas_rel = Canvas(relation_frame, width=20, height=20)
        self.relation_frame = Frame(canvas_rel)
        scroll2 = Scrollbar(relation_frame,
                            orient=VERTICAL,
                            command=canvas.yview)
        canvas_rel.config(yscrollcommand=scroll2.set)
        canvas_rel_item = canvas_rel.create_window((0, 0),
                                                   window=self.relation_frame,
                                                   anchor='w')
        self.relation_frame.bind("<Configure>", myfunction2)
        canvas_rel.bind('<Configure>', onCanvasConfigure2)
        canvas_rel.pack(side=LEFT, fill=BOTH, expand=True)
        scroll2.pack(side=RIGHT, fill=Y)

        description_text_frame = Frame(tabs)
        description_text_frame.grid_rowconfigure(0, weight=1)
        description_text_frame.grid_columnconfigure(0, weight=1)
        self.description_text = Text(description_text_frame,
                                     font="FreeMono 10",
                                     wrap=WORD)
        self.description_text.insert('1.0', "description")
        self.description_text.bind('<Leave>', self.save_event)
        self.description_text.bind('<KeyPress>', self.save_new_desc)
        self.description_text.bind('<Control-z>', self.discard_text_changes)
        scroll = Scrollbar(description_text_frame,
                           orient=VERTICAL,
                           command=self.description_text.yview)
        self.description_text.config(yscrollcommand=scroll.set)
        self.description_text.grid(column=0, row=0, stick="news")
        scroll.grid(column=1, row=0, stick="news")

        tabs.add(description_text_frame, text="description")
        tabs.add(activity_frame, text="activities")
        tabs.add(relation_frame, text="related tasks")
        tabs.pack(fill=BOTH, expand=True)

        self.complete_task_frame = ttk.Frame(self.task_frame)
        self.complete_task_frame.grid_rowconfigure(0, weight=1)
        self.complete_task_frame.grid_columnconfigure(0, weight=1)
        self.label_completed = Label(self.complete_task_frame,
                                     text="completed at: 0000-00-00",
                                     font="LiberationMono-Bold 10")
        self.description_completed_text = Text(self.complete_task_frame,
                                               font="FreeMono 10",
                                               height=10,
                                               wrap=WORD)
        self.description_completed_text.insert("1.0", "completed")
        self.description_completed_text.config(state=DISABLED)
        self.label_completed.pack()
        self.description_completed_text.pack(fill=X)

        self.button_frame = Frame(self.task_frame)
        rel_button_frame = Frame(self.button_frame)
        self.rel_button = ttk.Button(rel_button_frame,
                                     text="Relate task",
                                     command=self.add_relationship)
        rel_label = Label(rel_button_frame,
                          text="id: ",
                          font="LiberationMono-Bold 10")
        self.rel_id_string = StringVar()
        rel_entry = Entry(rel_button_frame,
                          width=36,
                          textvariable=self.rel_id_string,
                          font="Keraleeyam-Regular 10")
        self.rel_type_string = StringVar()
        combo = ttk.Combobox(rel_button_frame,
                             width=7,
                             textvariable=self.rel_type_string,
                             values=("CHILD", "PARENT"))
        rel_label.pack(side=LEFT, padx=5)
        rel_entry.pack(side=LEFT, padx=5)
        combo.pack(side=LEFT, padx=10)
        self.rel_button.pack(side=LEFT, padx=10)
        rel_button_frame.pack(side=LEFT)

        self.reschedule_button = ttk.Button(self.button_frame,
                                            text="Reschedule",
                                            command=self.reschedule_event)
        self.complete_button = ttk.Button(self.button_frame,
                                          text="Complete",
                                          command=self.complete_event)
        self.reschedule_button.pack(side=RIGHT, padx=10)
        self.complete_button.pack(side=RIGHT, padx=10)

        title_label.pack(fill=X, pady=5, padx=10)
        id_label.pack(fill=X, pady=5, padx=10)
        ldabel_text_frame.pack(pady=5, padx=10)
        tags_frame.pack(fill=X, pady=5, padx=100)
        main_task_frame.pack(padx=100, pady=5, expand=True, fill=BOTH)

    def drow_list(self):
        self.tabs = ttk.Notebook(self.list_frame)
        self.tabs.pack(fill=BOTH, expand=True)
        self.list_day = Listbox(self.tabs,
                                selectmode=SINGLE,
                                exportselection=False)
        self.list_day.bind("<<ListboxSelect>>", self.update_main_frame_day)
        self.list_all = Listbox(self.tabs,
                                selectmode=SINGLE,
                                exportselection=False)
        self.list_all.bind("<<ListboxSelect>>", self.update_main_frame_day)
        self.list_old = Listbox(self.tabs,
                                selectmode=SINGLE,
                                exportselection=False)
        self.list_old.bind("<<ListboxSelect>>", self.update_main_frame_day)
        self.tabs.add(self.list_day, text="Today")
        self.tabs.add(self.list_all, text="WIP")
        self.tabs.add(self.list_old, text="History")

    def add_relationship(self):
        task = self.tcont.search_task([self.rel_id_string.get()])[0]
        task = None if task.id == self.current_task.id else task
        if task and self.rel_type_string.get() == "CHILD":
            self.current_task.childs.append(task)
            task.parents.append(self.current_task)
            self.update_task_frame()
            self.tcont.save()
        elif task and self.rel_type_string.get() == "PARENT":
            self.current_task.parents.append(task)
            task.childs.append(self.current_task)
            self.update_task_frame()
            self.tcont.save()

    def discard_text_changes(self, event=None):
        self.description_text.delete("1.0", END)
        self.new_description = self.current_task.description
        self.description_text.insert("1.0", self.new_description)

    def add_new_tag(self, event):
        if len(self.tags_container.winfo_children()) <= 5:
            TagLabel(self.tags_container,
                     text=self.tags_new_task_string.get(),
                     bg="yellow",
                     clickdestroy=True).pack(padx=5, side=LEFT)
            self.tags_new_task_string.set("")

    def add_task_tag(self, event):
        if len(self.tags_frame.winfo_children()) <= 5:
            TagLabel(self.tags_frame,
                     text=self.tags_task_string.get(),
                     bg="yellow",
                     clickdestroy=True).pack(padx=5, side=LEFT)
            self.tags_task_string.set("")
            self.save_tags()

    def save_event(self, event=None):
        self.new_description = self.description_text.get("1.0", END)[:-1]
        self.current_task.description = self.new_description
        self.tcont.save()

    def quit_event(self, event=None):
        if self.current_task:
            self.save_event()
        self.destroy()

    def save_tags(self, event=None):
        tags = []
        for w in self.tags_frame.winfo_children():
            tags.append(w.get_text())
        self.current_task.tags = tags
        self.tcont.save()

    def save_new_desc(self, event):
        self.new_description = self.description_text.get("1.0", END)[:-1]

    def update_label_reschedule_time(self, event=None):
        self.hour_label.config(text="{}h {}m".format(
            int(int(self.hour_string.get()) /
                6), int(int(self.hour_string.get()) % 6 * 10)))

    def update_label_reschedule_eff_time(self, event=None):
        self.hour_eff_label.config(text="{}h {}m".format(
            int(int(self.hour_effective_string.get()) /
                6), int(int(self.hour_effective_string.get()) % 6 * 10)))

    def update_label_new_time(self, event=None):
        self.hour_new_label.config(text="{}h {}m".format(
            int(int(self.hour_new_string.get()) /
                6), int(int(self.hour_new_string.get()) % 6 * 10)))

    def fetch_activities(self):
        for w in self.activity_frame_main.winfo_children():
            w.destroy()
        hcount = 0
        for activity in self.current_task.activities:
            hcount += activity.hour
        if int(hcount / 6) > 24:
            ttk.Label(
                self.activity_frame_main,
                text="total time spent: {}d {}h {}m".format(
                    int(hcount / (6 * 24)),
                    int((hcount - int(hcount / (6 * 24)) * (6 * 24)) / 6),
                    int((hcount - int(hcount / (6 * 24)) * (6 * 24)) % 6 *
                        10)),
                font="LiberationMono-Bold 10",
                padding="0 10 0 0").pack(fill=X, padx=10)
        else:
            ttk.Label(self.activity_frame_main,
                      text="total time spent: {}h {}m".format(
                          int(hcount / 6), int(hcount % 6 * 10)),
                      font="LiberationMono-Bold 10",
                      padding="0 10 0 0").pack(fill=X, padx=10)
        for activity in self.current_task.activities:
            ttk.Label(self.activity_frame_main,
                      text="date: {}\t\t\ttime spent: {}h {}m".format(
                          activity.date, int(activity.hour / 6),
                          int(activity.hour % 6 * 10)),
                      font="LiberationMono-Bold 10",
                      padding="0 25 0 10").pack(fill=X, padx=10)
            DText(self.activity_frame_main,
                  activity.description,
                  font="FreeMono 10",
                  wrap=WORD).pack(fill=X, padx=10, expand=True)

    def fetch_rels(self):
        for w in self.relation_frame.winfo_children():
            w.destroy()

        def bind_dclick(task):
            wlist = self.tabs.winfo_children()
            for w in wlist:
                w.selection_clear(0, END)
            self.update_task_frame(task=task)

        for task in self.current_task.childs:
            rel_frame(self.relation_frame, task, "CHILD ",
                      bind_dclick).pack(fill=X, padx=5)
        for task in self.current_task.parents:
            rel_frame(self.relation_frame, task, "PARENT",
                      bind_dclick).pack(fill=X, padx=5)

    def fetch_list_event(self, event=None):
        self.fetch_old()
        self.fetch_list()

    def fetch_old(self):
        self.list_old.delete(0, END)

        if self.filter_text_string.get() == "":
            self.task_list_old = self.tcont.old_list
        else:
            self.task_list_old = filtask.map_filter[
                self.filter_mod_string.get()](self.tcont.old_list,
                                              self.filter_text_string.get())

        count = 0
        for item in self.task_list_old:
            self.list_old.insert(count, item.name)
            count += 1

    def fetch_list(self):
        self.list_all.delete(0, END)
        self.list_day.delete(0, END)

        if self.filter_text_string.get() == "":
            self.task_list_day = self.tcont.day_tasks_list
            self.task_list_wip = self.tcont.task_list
        else:
            self.task_list_day = filtask.map_filter[
                self.filter_mod_string.get()](self.tcont.day_tasks_list,
                                              self.filter_text_string.get())
            self.task_list_wip = filtask.map_filter[
                self.filter_mod_string.get()](self.tcont.task_list,
                                              self.filter_text_string.get())

        count = 0
        for item in self.task_list_day:
            self.list_day.insert(count, item.name)
            count += 1

        count = 0
        for item in self.task_list_wip:
            self.list_all.insert(count, item.name)
            count += 1

        widget = self.tabs.winfo_children()[self.tabs.index(
            self.tabs.select())]
        widget.selection_set(0)

    def update_main_frame_day(self, event):
        widget = event.widget
        wlist = self.tabs.winfo_children()
        wlist.pop(self.tabs.index(self.tabs.select()))
        for w in wlist:
            w.selection_clear(0, END)
        if len(widget.curselection()) > 0:
            self.update_task_frame()
            for w in self.main_frame.winfo_children():
                w.pack_forget()
            self.task_frame.pack(fill=BOTH, expand=True)

    def update_task_frame(self, task=None):
        widget = self.tabs.winfo_children()[self.tabs.index(
            self.tabs.select())]
        if len(widget.curselection()) > 0 or task:
            if task:
                self.current_task = task
            else:
                if self.tabs.index(self.tabs.select()) == 0:
                    self.current_task = self.task_list_day[
                        widget.curselection()[0]]
                elif self.tabs.index(self.tabs.select()) == 1:
                    self.current_task = self.task_list_wip[
                        widget.curselection()[0]]
                else:
                    self.current_task = self.task_list_old[
                        widget.curselection()[0]]
            self.title_string.set(self.current_task.name)
            self.id_string.set(self.current_task.id)
            self.description_text.config(state=NORMAL)
            self.description_text.delete(1.0, END)
            self.new_description = self.current_task.description
            self.description_text.insert('1.0', self.new_description)

            for w in self.tags_frame.winfo_children():
                w.destroy()

            if self.current_task.get_status() == "COMPLETED":
                self.description_text.config(state=DISABLED)
                self.button_frame.pack_forget()
                self.description_completed_text.config(state=NORMAL)
                self.description_completed_text.delete("1.0", END)
                self.description_completed_text.insert(
                    "1.0", self.current_task.completed_comment)
                self.description_completed_text.config(state=DISABLED)
                self.label_completed.config(text="completed at: {}".format(
                    self.current_task.completed_date.isoformat()))
                self.complete_task_frame.pack(fill=X, padx=100, pady=50)
                self.tags_task_entry.grid_forget()
                for tag in self.current_task.tags:
                    TagLabel(self.tags_frame, text=tag,
                             bg="yellow").pack(padx=5, side=LEFT)

            else:
                self.description_text.config(state=NORMAL)
                self.complete_task_frame.pack_forget()
                self.button_frame.pack(pady=35, padx=60, fill=X)
                self.tags_task_entry.grid(column=1, row=0)
                for tag in self.current_task.tags:
                    TagLabel(self.tags_frame,
                             text=tag,
                             bg="yellow",
                             clickdestroy=True).pack(padx=5, side=LEFT)

            if self.current_task.get_status() == "WAITING":
                self.complete_button.config(state=DISABLED)
            else:
                self.complete_button.config(state=NORMAL)

            self.rel_type_string.set("")
            self.rel_id_string.set("")
            self.fetch_activities()
            self.fetch_rels()
            if self.current_task.get_status(
            ) == "NEXT" or self.current_task.get_status() == "PENDING":
                self.label_state.config(text="state: {} \u2192 {}".format(
                    self.current_task.get_status(),
                    str(self.current_task.schedule.start_date)))
            else:
                self.label_state.config(
                    text="state: {}".format(self.current_task.get_status()))
            self.label_created.config(text="created: {}".format(
                str(self.current_task.creation_date)))
            self.label_due.config(text="due date: {}".format(
                self.current_task.due_date.isoformat()))
            self.label_priority.config(
                text="priotity: {}".format(int(self.current_task.priority)))
            self.label_time.config(text="time to spend next: {}h {}m".format(
                int(self.current_task.schedule.hour /
                    6), int(self.current_task.schedule.hour % 6 * 10)))

    def complete_event(self):
        self.task_frame.pack_forget()
        self.title_complete_string.set("Completing task: {}".format(
            self.current_task.id))
        self.complete_text.delete(1.0, END)
        self.complete_frame.pack(fill=X, padx=70)

    def complete_task_event(self):
        self.current_task.description = self.description_text.get("1.0",
                                                                  END)[:-1]
        self.current_task.complete(self.complete_text.get("1.0", END))
        self.complete_frame.pack_forget()
        self.update_task_frame()
        self.tcont.refresh_day_tasks()
        self.fetch_list()
        self.task_frame.pack(fill=BOTH, expand=True)
        self.tcont.save()

    def cancel_event(self):
        childs = self.main_frame.winfo_children()
        for child in childs:
            child.pack_forget()
        self.task_frame.pack(fill=BOTH, expand=True)

    def new_event(self):
        self.name_new_task_string.set("")
        self.description_new_text.delete("1.0", END)
        self.calendar_due.selection_set(datetime.date.today())
        self.calendar_start.selection_set(datetime.date.today())
        self.stick_new.set(0)
        self.priority_new_string.set(1)
        self.hour_new_string.set(1)
        self.tags_new_task_string.set("")
        self.hour_new_label.config(text="{}h {}m".format(
            int(int(self.hour_new_string.get()) /
                6), int(int(self.hour_new_string.get()) % 6 * 10)))
        for w in self.tags_container.winfo_children():
            w.destroy()
        for w in self.main_frame.winfo_children():
            w.pack_forget()
        self.new_task_frame.pack(fill=X, padx=70)

    def new_task_event(self):
        istoday = False
        if datetime.date.fromisoformat(self.calendar_start.get_date(
        )) == datetime.date.today() and datetime.date.fromisoformat(
                self.calendar_due.get_date()) == datetime.date.today():
            istoday = True
        tags = []
        for w in self.tags_container.winfo_children():
            tags.append(w.get_text())
        task = Task(name=self.name_new_task_string.get(),
                    description=self.description_new_text.get("1.0", END),
                    start_date=self.calendar_start.get_date(),
                    due_date=self.calendar_due.get_date(),
                    hour=int(self.hour_new_string.get()),
                    priority=int(self.priority_new_string.get()),
                    is_today=istoday,
                    tags=tags,
                    is_sticked=bool(self.stick_new.get()))
        self.tcont.add_task(task)
        self.tcont.save()
        self.fetch_list()
        self.new_task_frame.pack_forget()
        wlist = self.tabs.winfo_children()
        for w in wlist:
            w.selection_clear(0, END)
        self.update_task_frame(task=self.tcont.task_list[-1])
        self.task_frame.pack(fill=BOTH, expand=True)

    def reschedule_event(self):
        self.title_reschedule_string.set("Reschedule task: {}".format(
            self.current_task.id))
        tomorrow = datetime.date.today() + datetime.timedelta(days=1)
        self.calendar.selection_set(tomorrow)
        self.hour_string.set(1)
        self.hour_effective_string.set(1)
        self.hour_label.config(text="0h 10m")
        self.hour_eff_label.config(text="0h 10m")
        self.reschedule_text.delete("1.0", END)
        self.stick.set(0)
        self.task_frame.pack_forget()
        self.reschedule_frame.pack(fill=X, padx=70)

    def reschedule_task_event(self):
        self.current_task.reschedule(Activity(
            self.reschedule_text.get("1.0", END)[:-1],
            int(self.hour_effective_string.get())),
                                     int(self.hour_string.get()),
                                     start_date=self.calendar.get_date(),
                                     is_sticked=bool(self.stick.get()))
        self.reschedule_frame.pack_forget()
        self.update_task_frame()
        self.task_frame.pack(fill=BOTH, expand=True)
        self.tcont.refresh_day_tasks()
        self.fetch_list()
        self.tcont.save()
예제 #9
0
class GUI(tk.Tk):
    PRIMARY_COLOR = "#fff"
    SECONDARY_COLOR = "#BDBDBD"
    BUTTON_COLOR = "#FF5733"
    NOW = datetime.now()
    DAY= NOW.day
    MONTH = NOW.month
    YEAR = NOW.year
    # PREDICTOR = predictor()
    def __init__(self):
        self.ignore_warning = False
        self.model = os.path.join(current_dir,"model/m.h5")
        self.graph_process = None
        self.predictor_process = None 
        tk.Tk.__init__(self)
        self.resizable(False,False)
        self.title("Load Predictor")
        num_biomass = 3
        num_biogas = 2
        num_solar = 2
        biomass_pv = 12.35
        biogas_pv = 14
        # Try to load previous configuration
        try:
            config_path = os.path.join(current_dir,"config.pickle")
            with open(config_path,"rb") as r:
                config = pickle.load(r)
                num_biomass = config["num_biomass"]
                num_biogas = config["num_biogas"]
                num_solar = config["num_solar"]
                biomass_pv = config["biomass_pv"]
                biogas_pv = config["biogas_pv"]
            
        except Exception as err:
            print(err)
        
        
        self.options = {
            "num_biomass":tk.IntVar(self,value=num_biomass),
            "num_biogas":tk.IntVar(self,value=num_biogas),
            "num_solar":tk.IntVar(self,value=num_solar),
            "biomass_pv":tk.DoubleVar(self,value=biomass_pv),
            "biogas_pv":tk.DoubleVar(self,value=biogas_pv),
            "use_gpu":tk.IntVar(self,value=0),
            "scatter":tk.IntVar(self,value=0),
            "fill":tk.IntVar(self,value=1)
        }
        self.mainframe = tk.Frame(self,bg=GUI.PRIMARY_COLOR)
        self.mainframe.config(width=300,height=250)
        self.mainframe.pack()
        self.add_option() # plot option frame
        self.add_calendar() # add calendar 
        self.add_generator_option() # add generator option frame
        self.add_control_button() # add start prediction button
        def on_close():
            try:
                subprocess.Popen.kill(self.graph_process)
            except:
                pass
            try:
                self.stop_prediction()
            except:
                pass
            self.destroy()     
        self.protocol("WM_DELETE_WINDOW", on_close)
        self.mainloop()
        
    def power_error_callback(self,title,message): # handle power failure event
        if not self.ignore_warning:
            """
                Yes -> True
                No -> False
                Cancel -> None
            """       
            value = messagebox.askokcancel(title,message)
            if value == True:
                self.pred.should_terminate = True # force to terminate 
                try:
                    subprocess.Popen.kill(self.graph_process)
                except:
                    pass
                
    def add_option(self):
        self.option_frame = tk.Frame(self.mainframe,bg=GUI.PRIMARY_COLOR)
        self.option_frame.grid(row=2,column =0,sticky="nwe")
        
        
        tk.Label(self.option_frame,text=" TF Option",bg=GUI.PRIMARY_COLOR).pack(anchor="nw")
        tk.Checkbutton(self.option_frame, 
                  text="Use GPU",
                  variable=self.options["use_gpu"],
                  bg=GUI.PRIMARY_COLOR).pack(anchor="nw")
        
        tk.Label(self.option_frame,text=" Plot Option",bg=GUI.PRIMARY_COLOR).pack(anchor="nw")
        tk.Checkbutton(self.option_frame, 
                  text="Scatter Plot",
                  variable=self.options["scatter"],
                #   command=lambda : toggle("scatter") ,
                  bg=GUI.PRIMARY_COLOR).pack(anchor="nw")

        tk.Checkbutton(self.option_frame, 
                  text="Fill Plot",
                  variable=self.options["fill"],
                #   command=lambda : toggle("scatter") ,
                  bg=GUI.PRIMARY_COLOR).pack(anchor="nw")
        tk.Label(self.option_frame,text=" Predict Interval (ms)",bg=GUI.PRIMARY_COLOR).pack(anchor="w")
        self.interval_scaler = tk.Scale(self.option_frame, from_=0, to=2500, orient=tk.HORIZONTAL,bg=GUI.PRIMARY_COLOR)
        self.interval_scaler.pack()
        self.interval_scaler.set(250) # set default value
        

    def add_calendar(self):
        tk.Label(self.mainframe,text="Select Prediction Date",bg=GUI.PRIMARY_COLOR).grid(row=1,column=1,columnspan=2,sticky="W")
        self.calendar_frame = tk.Frame(self.mainframe,bg=GUI.SECONDARY_COLOR)
        self.calendar_frame.grid(row=2,column=1)
        self.calendar = Calendar(self.calendar_frame,
                   font="Arial 10", selectmode='day',
                   date_pattern="y-mm-dd",
                    year=GUI.YEAR, month=GUI.MONTH, day=GUI.DAY)
        self.calendar.pack(fill="both", expand=True)
        
    def add_generator_option(self):
        self.gen_option_frame = tk.Frame(self.mainframe,bg=GUI.PRIMARY_COLOR)
        self.gen_option_frame.grid(row=3,column=1)
        # ADD SCALERS COLUMN 0
        tk.Label(self.gen_option_frame,text="Biomass Generator",bg=GUI.PRIMARY_COLOR).grid(row=1,column=0)
        tk.Scale(self.gen_option_frame, from_=0, to=15, orient=tk.HORIZONTAL,variable=self.options["num_biomass"],bg=GUI.PRIMARY_COLOR).grid(row=2,column=0)
       
        tk.Label(self.gen_option_frame,text="Biogas Generator",bg=GUI.PRIMARY_COLOR).grid(row=3,column=0)
        tk.Scale(self.gen_option_frame, from_=0, to=15, orient=tk.HORIZONTAL,variable=self.options["num_biogas"],bg=GUI.PRIMARY_COLOR).grid(row=4,column=0)
        
        tk.Label(self.gen_option_frame,text="Solar Cell Generator",bg=GUI.PRIMARY_COLOR).grid(row=5,column=0)
        tk.Scale(self.gen_option_frame, from_=0, to=15, orient=tk.HORIZONTAL,variable=self.options["num_solar"],bg=GUI.PRIMARY_COLOR).grid(row=6,column=0)
        
        
        # ADD SCALERS COLUMN 1
        tk.Label(self.gen_option_frame,text="Biomass Gen. Power (kWH)",bg=GUI.PRIMARY_COLOR).grid(row=1,column=1)
        tk.Scale(self.gen_option_frame, from_=0, to=100,digits=4,resolution =   0.01, orient=tk.HORIZONTAL,variable=self.options["biomass_pv"],bg=GUI.PRIMARY_COLOR).grid(row=2,column=1)
       
        tk.Label(self.gen_option_frame,text="Biogas Gen. Power (kWH)",bg=GUI.PRIMARY_COLOR).grid(row=3,column=1)
        tk.Scale(self.gen_option_frame, from_=0, to=100,digits=4,resolution =   0.01, orient=tk.HORIZONTAL,variable=self.options["biogas_pv"],bg=GUI.PRIMARY_COLOR).grid(row=4,column=1)
        
        
    def stop_prediction(self):
        try:
            self.pred.should_terminate = True
        except:
            pass
        try:
            subprocess.Popen.kill(self.graph_process)
        except:
            pass
        
        
    def save_config(self):
        config = {
            "num_biomass": self.options["num_biomass"].get(),
            "num_biogas":self.options["num_biogas"].get(),
            "num_solar":self.options["num_solar"].get(),
            "biomass_pv":self.options["biomass_pv"].get(),
            "biogas_pv":self.options["biogas_pv"].get()
        }
        with open('config.pickle', 'wb') as f:
            pickle.dump(config, f)
        messagebox.showinfo("Save","Save Configuration Succeeded!")
        

    def add_control_button(self):
        self.control_button_frame = tk.Frame(self.mainframe,bg=GUI.PRIMARY_COLOR)
        self.control_button_frame.grid(row=2,column=2,sticky="NS")
        
        self.start_button = tk.Button(self.control_button_frame,text="Start Predicting")
        self.start_button.config(command=self.predict)
        self.start_button.grid(row=0,column=0,sticky='nesw')
        
        self.stop_button = tk.Button(self.control_button_frame,text="Stop Predicting")
        self.stop_button.config(command=self.stop_prediction)
        self.stop_button.grid(row=1,column=0,sticky='nesw')
        
        self.save_config_button = tk.Button(self.control_button_frame,text="Save\nConfiguration")
        self.save_config_button.config(command=self.save_config)
        self.save_config_button.grid(row=2,column=0,sticky='nesw')
        
        
        self.control_button_frame.grid_columnconfigure(0, weight=1, uniform="group1")
        # self.control_button_frame.grid_columnconfigure(1, weight=1, uniform="group1")
        self.control_button_frame.grid_rowconfigure(0, weight=1)
        self.control_button_frame.grid_rowconfigure(1, weight=1)
        self.control_button_frame.grid_rowconfigure(2, weight=1)
        
    def predict(self):
        self.ignore_warning = False
        try:
            self.pred.should_terminate = True
            print("Successfully terminated predicting thread !")
        except Exception as err:
            print(err)
        
        # KILL EXISTING PROCESS
        try:
            subprocess.Popen.kill(self.graph_process)
        except Exception as err:
            print(err)
        
        date = (self.calendar.get_date())
        date = datetime.strptime(date,"%Y-%m-%d")
        import threading as th
        import multiprocessing as mp
        daydelta = 0
        fill_plot=bool(self.options["fill"].get()) # fill plot
        scatter_plot = bool(self.options["scatter"].get()) # use scatter plot
        print("plot options",fill_plot,scatter_plot)
        use_gpu = bool(self.options["use_gpu"].get()) # use gpu for tensorflow 
        num_biomass = self.options["num_biomass"].get()
        num_biogas = self.options["num_biogas"].get()
        num_solar = self.options["num_solar"].get()
        biomass_pv = self.options["biomass_pv"].get()
        biogas_pv = self.options["biogas_pv"].get()
        period = 15
        self.pred = predictor(dt=date,model_path=self.model,use_gpu=use_gpu,message_callback=self.power_error_callback) # creat new instance of predictor
        self.pred.iteration_delay = self.interval_scaler.get()/1000 # self.predictor loop delay
        self.pred.BIOMASS_PV = biomass_pv
        self.pred.BIOGAS_PV = biogas_pv
        self.pred.num_biomass = num_biomass
        self.pred.num_biogas = num_biogas
        self.pred.num_solar = num_solar
        pred_thread = th.Thread(target=self.pred.run)
        pred_thread.start()
        self.graph_process = subprocess.Popen([
            "python",
            "plot_load.py",
            "--date",str(date.date()),
            "--scatter-plot", str(scatter_plot),
            "--fill-plot", str(fill_plot)
        ])
예제 #10
0
class Application(tk.Frame):
    def __init__(self, master=None, config=None):
        super().__init__(master)
        self.master = master
        self.config = config
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        ## Add Calender
        self.l1 = tk.Label(self, text="Start")
        self.l1.grid(row=0, column=0, sticky='nw')
        self.calBegin = Calendar(self,
                                 selectmode='day',
                                 day=self.config.startTime.day,
                                 month=self.config.startTime.month,
                                 year=self.config.startTime.year)
        self.calBegin.grid(row=1, column=1)
        temp = tk.DoubleVar(value=self.config.startTime.hour)
        self.hourBegin = tk.Spinbox(self,
                                    from_=0,
                                    to=23,
                                    increment=1,
                                    width=2,
                                    textvariable=temp)
        self.hourBegin.grid(row=1, column=2)
        temp = tk.DoubleVar(value=(int(self.config.startTime.minute / 15) *
                                   15))
        self.minuteBegin = tk.Spinbox(self,
                                      from_=0,
                                      to=45,
                                      increment=15,
                                      width=2,
                                      textvariable=temp)
        self.minuteBegin.grid(row=1, column=3)
        self.l2 = tk.Label(self, text="Ende")
        self.l2.grid(row=2, column=0, sticky='nw')
        self.calEnd = Calendar(self,
                               selectmode='day',
                               day=self.config.endTime.day,
                               month=self.config.endTime.month,
                               year=self.config.endTime.year)
        self.calEnd.grid(row=3, column=1)
        temp = tk.DoubleVar(value=7)
        self.hourEnd = tk.Spinbox(self,
                                  from_=0,
                                  to=23,
                                  increment=1,
                                  width=2,
                                  textvariable=temp)
        self.hourEnd.grid(row=3, column=2)
        temp = tk.DoubleVar(value=30)
        self.minuteEnd = tk.Spinbox(self,
                                    from_=0,
                                    to=45,
                                    increment=15,
                                    width=2,
                                    textvariable=temp)
        self.minuteEnd.grid(row=3, column=3)
        self.l3 = tk.Label(self, text="StartSoC /%")
        self.l3.grid(row=4, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.startSoC)
        self.startSoC = tk.Spinbox(self,
                                   from_=0,
                                   to=100,
                                   increment=1,
                                   width=3,
                                   textvariable=temp)
        self.startSoC.grid(row=4, column=1)
        self.l4 = tk.Label(self, text="EndSoC /%")
        self.l4.grid(row=5, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.endSoC)
        self.endSoC = tk.Spinbox(self,
                                 from_=0,
                                 to=100,
                                 increment=1,
                                 width=3,
                                 textvariable=temp)
        self.endSoC.grid(row=5, column=1)
        self.l5 = tk.Label(self, text="Charging power /kW")
        self.l5.grid(row=6, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.chargePower)
        self.chargePower = tk.Spinbox(self,
                                      from_=1,
                                      to=22,
                                      increment=1,
                                      width=3,
                                      textvariable=temp)
        self.chargePower.grid(row=6, column=1)
        self.l6 = tk.Label(self, text="capacity /kWh")
        self.l6.grid(row=7, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.capacity)
        self.capacity = tk.Spinbox(self,
                                   from_=1,
                                   to=130,
                                   increment=1,
                                   width=3,
                                   textvariable=temp)
        self.capacity.grid(row=7, column=1)
        self.l7 = tk.Label(self, text="solar peak power /kW")
        self.l7.grid(row=8, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.solarPeakPower)
        self.solarPeakPower = tk.Spinbox(self,
                                         from_=0,
                                         to=30,
                                         increment=0.5,
                                         width=3,
                                         textvariable=temp)
        self.solarPeakPower.grid(row=8, column=1)
        self.l8 = tk.Label(self, text="solar cost ct/kWh")
        self.l8.grid(row=9, column=0, sticky='nw')
        temp = tk.DoubleVar(value=config.solarCost * 100)
        self.solarCost = tk.Spinbox(self,
                                    from_=1,
                                    to=30,
                                    increment=0.5,
                                    width=3,
                                    textvariable=temp)
        self.solarCost.grid(row=9, column=1)
        self.quit = tk.Button(self, text="apply", command=self.quit_action)
        self.quit.grid(row=10)

    def quit_action(self):
        self.config.startTime = datetime.datetime.fromisoformat(
            isostring_from_calendar_hour_minute(self.calBegin.get_date(),
                                                self.hourBegin.get(),
                                                self.minuteBegin.get()))
        self.config.endTime = datetime.datetime.fromisoformat(
            isostring_from_calendar_hour_minute(self.calEnd.get_date(),
                                                self.hourEnd.get(),
                                                self.minuteEnd.get()))
        self.config.chargePower = float(self.chargePower.get())
        self.config.startSoC = float(self.startSoC.get())
        self.config.endSoC = float(self.endSoC.get())
        self.config.capacity = float(self.capacity.get())
        self.config.solarCost = float(self.solarCost.get()) / 100
        self.config.solarPeakPower = float(self.solarPeakPower.get())
        calc = Calc(config)
        results = calc.charge()
        msg.showinfo(title="Congratulations",
                     message="You haved saved " + str(results.savings) +
                     " €\nYour pv contributed " +
                     str(results.solarQuote * 100) + " percent of your charge")
        fig, ax1 = plt.subplots()
        fig.subplots_adjust(right=0.75)
        ax1.set_xlabel('hours')
        ax1.set_ylabel('price €/kWh')
        ax1.plot(results.hours, results.prices)
        ax2 = ax1.twinx()
        ax2.set_ylabel('power in kW', color='red')
        ax2.plot(results.hours, results.solarPower, color='orange')
        ax2.plot(results.hours, results.charging, color='red')
        ax3 = ax1.twinx()
        ax3.spines.right.set_position(("axes", 1.2))
        ax3.set_ylabel('SoC in percent', color='green')
        ax3.plot(results.hours, results.SoC, color='green')
        fig.tight_layout()
        plt.gcf().autofmt_xdate()
        plt.get_current_fig_manager().canvas.set_window_title("Results")
        plt.title("Market prices over your selected time frame")
        plt.show()
        plt.close()
예제 #11
0
class StockEntry:
    def __init__(self, master):
        self.master = master
        self.master.geometry('1480x750+100+50')
        self.master.title('Activity Entry')
        self.master.configure(background='#A1CDEC')
        self.CreateWidgets()

    def CreateWidgets(self):

        Frame1 = tk.Frame(self.master,
                          bg='#A1CDEC')  #this is the fram for the application
        Frame1.grid()

        #this is the label for the title of the application
        self.mainLabel = tk.Label(Frame1,
                                  text="STOCK ACTIVITY ENTRY",
                                  bd=2,
                                  relief="solid",
                                  font=("Lucida Grande", 30, "bold"),
                                  fg="black",
                                  bg="#990000")
        self.mainLabel.grid(row=0, column=2)

        #entry variables
        self.date = tk.StringVar()
        self.symbol = tk.StringVar()
        self.transaction = tk.StringVar()
        self.quantity = tk.StringVar()
        self.price = tk.DoubleVar()

        #these are stock activity entry labels

        #stock calendar and entry
        self.calendar = Calendar(Frame1,
                                 selectmode='day',
                                 date_pattern='yyyy-mm-dd')
        self.calendar.grid(row=1, column=0)
        self.dateEntry = tk.Label(Frame1, text='')
        self.dateEntry.grid(row=2, column=0)
        self.dateEntry.config(width=22, relief=tk.RIDGE)

        #stock symbol label
        self.symLabel = tk.Label(Frame1,
                                 text="Stock Symbol",
                                 font=("Gothic Bold", 18, 'bold'),
                                 fg="#333333")
        self.symLabel.grid(row=1, column=1)
        self.symEntry = tk.Entry(Frame1, textvariable=self.symbol)
        self.symEntry.grid(row=2, column=1)
        self.symEntry.config(width=25, relief=tk.RIDGE)

        #transaction type label
        self.transLabel = tk.Label(Frame1,
                                   text="Transaction (BUY/SELL)",
                                   font=("Gothic Bold", 18, 'bold'),
                                   fg="#333333")
        self.transLabel.grid(row=1, column=2)
        self.transEntry = tk.Entry(Frame1, textvariable=self.transaction)
        self.transEntry.grid(row=2, column=2)
        self.transEntry.config(width=25, relief=tk.RIDGE)

        #stock quantity label
        self.quantLabel = tk.Label(Frame1,
                                   text="Quantity",
                                   font=("Gothic Bold", 18, 'bold'),
                                   fg="#333333")
        self.quantLabel.grid(row=1, column=4)
        self.quantEntry = tk.Entry(Frame1, textvariable=self.quantity)
        self.quantEntry.grid(row=2, column=4)
        self.quantEntry.config(width=25, relief=tk.RIDGE)

        #transacted stock price label
        self.priceLabel = tk.Label(Frame1,
                                   text="Price",
                                   font=("Gothic Bold", 18, 'bold'),
                                   fg="#333333")
        self.priceLabel.grid(row=1, column=9)
        self.priceEntry = tk.Entry(Frame1, textvariable=self.price)
        self.priceEntry.grid(row=2, column=9)
        self.priceEntry.config(width=25, relief=tk.RIDGE)

        #Date selection
        def SelectDate():
            self.date = self.calendar.get_date()
            self.dateEntry.config(text=self.date)

        #this adds user entry to the database
        def Record():
            Item1 = self.symbol.get()
            Item2 = self.transaction.get()
            Item3 = self.quantity.get()
            #Item4 = isinstance(self.price.get(),float)

            if (Item1.isalpha() and Item2.isalpha() and Item3.isdigit()
                    and isinstance(self.price.get(), float)):

                tkinter.messagebox.showinfo(
                    "Correct Date Entires",
                    "Saved Successfully in Stocks Database")
                #self.valid_message.config(text="Saved Successfully in Stocks Database")

                #Creates a database or connects to one
                conn = sqlite3.connect('stocks.db')

                #Create cursor
                c = conn.cursor()

                #Insert to stocks table
                c.execute(
                    "INSERT INTO stocks VALUES (:date, :symbol, :transaction, :quantity, :price)",
                    {
                        'date': self.calendar.get_date(),
                        'symbol': self.symbol.get(),
                        'transaction': self.transaction.get(),
                        'quantity': self.quantity.get(),
                        'price': round(self.price.get(), 2)
                    })

                #Commit changes
                conn.commit()

                #Clse connection
                conn.close()
                return True
            else:
                tkinter.messagebox.showwarning("Wrong Data",
                                               "Invalid data input")
                self.symbol.set('')
                self.transaction.set('')
                self.quantity.set(0)
                self.price.set(0.0)
                return False

        #Create searches function that searches the database and displays on the screen
        def Search():
            #Creates a database or connects to one
            conn = sqlite3.connect('stocks.db')

            #Create cursor
            c = conn.cursor()

            #stocks table cloumns
            colns = (self.calendar.get_date(), self.symbol.get(),
                     self.transaction.get(), self.quantity.get(),
                     round(self.price.get(), 2))

            #Query the database
            c.execute(
                "SELECT * FROM stocks WHERE date=? AND symbol=? AND trans=? AND quantity=? AND price=?",
                colns)
            records = c.fetchall()

            if not records:
                tkinter.messagebox.showwarning(
                    "Wrong Search", "Search returned nothing on search")

            else:
                #Loop through results
                print_records = ''
                for record in records:
                    print_records += str(record[0]) + "  " + str(
                        record[1]) + "  " + str(record[2]) + "   " + str(
                            record[3]) + "  " + "$" + str(record[4]) + "\n"

                #this displays the result from the search button clicked
                self.queryLabel = tk.Label(Frame1,
                                           text=print_records,
                                           font=("Lucida Grande", 17, 'bold'),
                                           fg="#333333")
                self.queryLabel.grid(row=11, column=0, columnspan=14)

                #Close Connection
                conn.close()

        #Resets the user input entry
        def Reset():
            self.symbol.set('')
            self.transaction.set('')
            self.quantity.set(0)
            self.price.set(0.0)

        #this creates an exported txt file of stock activities
        def ExportTxt():

            #Creates a database or connects to one
            conn = sqlite3.connect('stocks.db')

            #Create cursor
            c = conn.cursor()

            c.execute(
                "SELECT DISTINCT date, symbol, trans, quantity, price FROM stocks WHERE quantity > 0 ORDER BY date DESC"
            )
            exp_txt = c.fetchall()

            self.text_file = open('stock_activity.txt', 'w')

            #Loop through records
            txt_line = ''
            for line in exp_txt:
                txt_line += "User Activity: " + " " + str(
                    line[0]) + "  " + str(line[1]) + "  " + str(
                        line[2]) + "  " + str(line[3]) + "  " + "$" + str(
                            line[4]) + "\n"
                self.text_file.write(txt_line)
            self.text_file.close()

            #Close Connection
            conn.close()

        #Kills the application
        def iExit():
            iExit = tkinter.messagebox.askyesno("Validate Entry Widget",
                                                "Confirm if you want to exit")
            if iExit > 0:
                self.master.destroy()
                return

        #these are for the entry buttons
        #date button
        self.dateButton = tk.Button(Frame1,
                                    text="Select Date",
                                    font=("Gothic Bold", 15),
                                    bd=5,
                                    relief=tk.RAISED,
                                    padx=12,
                                    pady=12,
                                    command=SelectDate)
        self.dateButton.grid(row=5, column=0)

        #record button
        self.recordButton = tk.Button(Frame1,
                                      text="Record",
                                      font=("Gothic", 15),
                                      bd=5,
                                      relief=tk.RAISED,
                                      padx=12,
                                      pady=12,
                                      command=Record)
        self.recordButton.grid(row=7, column=1)

        #reset button
        self.resetButton = tk.Button(Frame1,
                                     text="Clear",
                                     font=("Gothic", 15),
                                     bd=5,
                                     relief=tk.RAISED,
                                     padx=12,
                                     pady=12,
                                     command=Reset)
        self.resetButton.grid(row=7, column=2)

        #search button
        self.searchButton = tk.Button(Frame1,
                                      text="Search",
                                      font=("Gothic", 15),
                                      bd=5,
                                      relief=tk.RAISED,
                                      padx=12,
                                      pady=12,
                                      command=Search)
        self.searchButton.grid(row=7, column=3)

        #export button
        self.exportButton = tk.Button(Frame1,
                                      text="Export",
                                      font=("Gothic Bold", 15),
                                      bd=5,
                                      relief=tk.RAISED,
                                      padx=12,
                                      pady=12,
                                      command=ExportTxt)
        self.exportButton.grid(row=9, column=6)

        #exit button
        self.ExitButton = tk.Button(Frame1,
                                    text="Exit",
                                    font=("Gothic Bold", 15),
                                    bd=5,
                                    relief=tk.RAISED,
                                    padx=12,
                                    pady=12,
                                    command=iExit)
        self.ExitButton.grid(row=9, column=2)
예제 #12
0
class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)

        # initializing for input how many periods in a day
        self.period_input = Spinbox(from_=3, to=8, wrap=True)

        # initializing for putting the start day for the calendar.
        self.start_date_input = Calendar(font='Arial 10',
                                         showweeknumbers=False)
        self.skip_days_input = Calendar(font='Arial 10', showweeknumbers=False)
        self.skip_days_input.bind("<<CalendarSelected>>", self.date_add)

        self.skip_days = []

        # variable for the start date
        self.start_date = datetime.datetime

        self.teach_names = ""
        self.teach_input = Entry(textvariable=self.teach_names, width=20)

        # to create input for the title of the spreadsheet.
        self.title = ""
        self.title_input = Entry(
            textvariable=self.title,
            width=20,
        )
        self.title_input_label = Label(text='Name for the file.')

        # for day cycle amount
        self.day_cycle = Spinbox(from_=1, to=8, wrap=True)
        self.day_cycle_window = 1

        self.schedule_day_full = {}
        self.repeating_window_cycle = 1

        week_counter_default = StringVar()
        week_counter_default.set("44")
        self.week_counter = Spinbox(from_=1,
                                    to=52,
                                    wrap=True,
                                    textvariable=week_counter_default)
        self.week_counter_label = Label(text='Number of weeks:')

        self.master = master
        self.init_window()

    # Creation of window
    def init_window(self):
        # changing the title of our master widget
        self.master.title("Computer Lab Booking Generator")

        self.pack(fill=BOTH, expand=1)

        # creating a button to quit the program
        quit_button = Button(self, text="Quit", command=self.client_exit)
        quit_button.place(x=9, y=590)

        # To input the amount of periods in a school day.
        self.period_input.place(x=150, y=50, width=30)
        period_input_label = Label(text='Number of Periods')
        period_input_label.place(x=1, y=50)

        # button to run the generate the spreadsheet.
        generate_button = Button(self,
                                 text='Generate',
                                 command=self.open_window)
        generate_button.place(x=250, y=590)

        # placing the calendar to pick start date.
        self.start_date_input.place(x=25, y=150)
        self.skip_days_input.place(x=25, y=375)
        start_date_label = Label(
            text='Please select a day to start your schedule on.')
        start_date_label.place(x=1, y=125)

        # placing the input for teacher names and it's label.
        self.teach_input.place(x=150, y=25)
        teach_input_label = Label(text='Teachers Names: ')
        teach_input_label.place(x=1, y=25)

        skip_days_input_label = Label(
            text=
            ' Select days that there is no school(ie PD Days, Holidays, etc) ',
            justify='left')
        skip_days_input_label.place(x=1, y=350)

        self.title_input.place(x=150, y=1)
        self.title_input_label.place(x=1, y=1)
        self.title_input.insert(END, 'Lab Booking')

        self.day_cycle.place(x=150, y=75, width=30)
        day_cycle_label = Label(text='Number of days in a cycle:')
        day_cycle_label.place(x=1, y=73)

        # Check box. Will show the day on each date if checked.
        self.show_day_number_check = IntVar()
        show_day_number = Checkbutton(root,
                                      text="Show day number on each day",
                                      variable=self.show_day_number_check,
                                      onvalue=1,
                                      offvalue=0,
                                      height=1,
                                      width=25)
        show_day_number.place(x=1, y=557)

        # Spinbox for selecting how many weeks the program will run for
        self.week_counter.place(x=150, y=100, width=30)
        self.week_counter_label.place(x=1, y=100)

    @staticmethod
    def client_exit():
        exit()

    # to convert from a datetime to excels epoch time.
    def excel_date(self):
        offset = 693594
        self.start_date = datetime.datetime.strptime(
            self.start_date_input.get_date(), '%Y-%m-%d')
        n = self.start_date.toordinal()
        return n - offset

    # excel epoch for skip list.
    def excel_date_skip_list(self):
        offset = 693594
        self.start_date = datetime.datetime.strptime(
            self.skip_days_input.get_date(), '%Y-%m-%d')
        n = self.start_date.toordinal()
        return n - offset

    # displays the dates beside the calendar used to pick dates with no school.
    def display_dates(self):
        date_list = []
        for dates in self.skip_days:
            date_list.append(self.regular_date(self, dates))
            dates_list_label = Label(text=date_list,
                                     wraplength=225,
                                     justify='center').place(x=275, y=425)

    # converts from an excel epoch time to datetime.
    @staticmethod
    def regular_date(self, date):
        offset = 693594
        new_date = date + offset
        final_date = datetime.datetime.strftime(
            datetime.datetime.fromordinal(new_date), '%b %d %Y')
        return final_date

    # makes a list of teachers names that was input into the GUI.
    def make_teach_list(self):
        self.teach_names = self.teach_input.get()
        teach_list = self.teach_names
        teach_list = [x.strip() for x in teach_list.split(',')]

    # adds days to a list in excel format to check against for formatting and day cycle counts.
    def date_add(self, date):
        added_date = self.excel_date_skip_list()
        if added_date in self.skip_days:
            self.skip_days.remove(added_date)
            self.display_dates()
            return
        if added_date not in self.skip_days:
            self.skip_days.append(added_date)
            self.display_dates()

    # Opens window for modifying each day individually.
    def open_window(self):
        self.repeating_window = Toplevel(root)
        repating_sched_label = Label(
            self.repeating_window,
            text='Repeating Schedule for Day {}'.format(
                self.day_cycle_window)).grid(row=1, column=1)
        self.p1_input = Entry(self.repeating_window)
        self.p2_input = Entry(self.repeating_window)
        self.p3_input = Entry(self.repeating_window)
        self.p4_input = Entry(self.repeating_window)
        self.p5_input = Entry(self.repeating_window)
        self.p6_input = Entry(self.repeating_window)
        self.p7_input = Entry(self.repeating_window)
        self.p8_input = Entry(self.repeating_window)

        self.repeating_window.geometry("300x200+300+300")
        placement_y = 2
        next_day_button = Button(self.repeating_window,
                                 text='Next Day',
                                 command=self.next_day).grid(row=19, column=2)

        for i in range(1, int(self.period_input.get()) + 1):
            period_label_new_window = Label(self.repeating_window,
                                            text='Period {}'.format(i)).grid(
                                                row=placement_y, column=1)
            if i == 1:
                self.p1_input.grid(row=placement_y, column=2)
                self.p1_input.insert(END, "Name:")

            if i == 2:
                self.p2_input.grid(row=placement_y, column=2)
                self.p2_input.insert(END, "Name:")

            if i == 3:
                self.p3_input.grid(row=placement_y, column=2)
                self.p3_input.insert(END, "Name:")

            if i == 4:
                self.p4_input.grid(row=placement_y, column=2)
                self.p4_input.insert(END, "Name:")

            if i == 5:
                self.p5_input.grid(row=placement_y, column=2)
                self.p5_input.insert(END, "Name:")

            if i == 6:
                self.p6_input.grid(row=placement_y, column=2)
                self.p6_input.insert(END, "Name:")

            if i == 7:
                self.p7_input.grid(row=placement_y, column=2)
                self.p7_input.insert(END, "Name:")

            if i == 8:
                self.p8_input.grid(row=placement_y, column=2)
                self.p8_input.insert(END, "Name:")

            placement_y += 2

    # Brings up the next day, and stores the values into a dict.
    def next_day(self):
        self.schedule_day = {
            1: self.p1_input.get(),
            2: self.p2_input.get(),
            3: self.p3_input.get(),
            4: self.p4_input.get(),
            5: self.p5_input.get(),
            6: self.p6_input.get(),
            7: self.p7_input.get(),
            8: self.p8_input.get()
        }

        for i in range(1, len(self.schedule_day) + 1):
            if self.schedule_day.get(i) == 'Name:' or self.schedule_day.get(
                    i) == '':
                self.schedule_day.update({i: 'default'})
            i += 1
        self.schedule_day_full[self.repeating_window_cycle] = self.schedule_day
        self.repeating_window_cycle += 1
        self.day_cycle_window += 1
        self.repeating_window.destroy()
        self.open_window()

        if self.day_cycle_window == int(self.day_cycle.get()) + 1:
            self.repeating_window.destroy()
            self.generate()
            self.day_cycle_window = 1
            self.schedule_day_full = {}
            self.repeating_window_cycle = 1
            return 'None'

    # generates the excel spreadsheet.
    def generate(self):
        # Create a workbook and add a worksheet.
        workbook = xlsxwriter.Workbook('{}.xlsx'.format(
            self.title_input.get()))
        link_page = workbook.add_worksheet('Link Page')
        worksheet = workbook.add_worksheet("Week1")
        self.start_date = datetime.datetime.strptime(
            self.start_date_input.get_date(), '%Y-%m-%d')
        self.make_teach_list()
        # Start from the first cell. Rows and columns are zero indexed.
        first_date_link_page = 0
        row = 1
        col = 1

        # Starts Weeks at num 1
        week = 1

        day = 1

        # getting the excel epoch time for the start date.
        start_date_excel = self.excel_date()
        # Cell formats
        date_format = workbook.add_format({'num_format': 'd mmm yyy'})
        center_format = workbook.add_format()
        colour_format = workbook.add_format()
        bold_format = workbook.add_format()
        justify_format = workbook.add_format()
        center_format.set_center_across()
        colour_format.set_bg_color('red')
        bold_format.set_bold(True)
        justify_format.set_align('left')

        # variables to format the period cells.
        period_row = 2
        period_number = int(self.period_input.get())

        link_page_row = 1
        link_page_column = 0
        link_page.write("A1", "Click These")
        link_page.set_column(0, 0, width=15)
        link_page.set_column(1, 1, width=30)

        # Checks to see if the start day falls between a monday and friday.
        if self.start_date.isoweekday() <= 5:

            # title for the week.
            worksheet.write(0, 0, 'Week {}'.format(week))

            # writes all the periods along the side at the top.
            for p in range(1, (period_number + 1)):
                worksheet.write(period_row, 0, 'Period {}'.format(p))
                period_row += 1

            for q in range(self.start_date.isoweekday(), 6):
                worksheet.write(row, col, start_date_excel, date_format)
                worksheet.set_column(col, col, 18, center_format)

                # checks if this is the first day of the week.
                if q == self.start_date.isoweekday():
                    first_date_link_page = start_date_excel

                # sets for putting the information in the periods.
                period_row = 3

                # formats to a red column if no school that day.
                if start_date_excel in self.skip_days:
                    worksheet.write(2, col, 'No School', colour_format)
                    for h in range(0, period_number - 1):
                        worksheet.write(period_row, col, " ", colour_format)
                        period_row += 1
                        h += 1

                # formats cells to use a list provided by user.
                if start_date_excel not in self.skip_days:
                    period = 1
                    for j in range(0, period_number - 1):
                        if int(self.day_cycle.get()) == 1 or day > int(
                                self.day_cycle.get()):
                            day = 1
                        if self.schedule_day_full[day][period] == 'default':
                            if self.teach_names:
                                worksheet.data_validation(
                                    period_row - 1, col, period_row, col, {
                                        'validate': 'list',
                                        'source': [self.teach_names]
                                    })
                            period_row += 1
                            period += 1

                        else:
                            worksheet.write(
                                period_row - 1, col,
                                self.schedule_day_full[day][period],
                                justify_format)
                            period_row += 1
                            period += 1

                    if self.show_day_number_check.get() == 1:
                        worksheet.write(period_row, col, "Day {}".format(day),
                                        justify_format)
                    day += 1
                col += 1
                start_date_excel += 1
                q += 1

                # Adds internal link so that you can navigate from the first page of the document.
                if q == 5:
                    second_date_link_page = start_date_excel
                    link_page.write_url(link_page_row, link_page_column,
                                        "internal:Week{}!A1".format(week),
                                        center_format, 'Week{}'.format(week))

                    link_page.write_rich_string(
                        link_page_row, link_page_column + 1, date_format,
                        '{}'.format(
                            self.regular_date(self, first_date_link_page)),
                        ' until ', date_format, '{}'.format(
                            self.regular_date(self, second_date_link_page)))
                    link_page_row += 1

                # adds link to first page with all the links to pages.
                worksheet.write_url('A12', "internal:'Link Page'!A1",
                                    bold_format, "First Page")

            # creates new worksheet for the next week.
            week += 1
            worksheet = workbook.add_worksheet('Week{}'.format(week))

            # Adds two to account for the weekend.
            start_date_excel += 2

            # Resets variables for the next round. Because they need to be back in the same cells.
            row = 1
            col = 1
            period_row = 2

        #if the day picked is a saturday or sunday.
        elif self.start_date.isoweekday() == 6:
            start_date_excel += 2

        elif self.start_date.isoweekday() == 7:
            start_date_excel += 1

        # This is for all the following weeks.
        for r in range(1, int(self.week_counter.get())):
            # title for the week.
            worksheet.write(0, 0, 'Week {}'.format(week))

            # writes all the dates at the top.
            for p in range(1, (period_number + 1)):
                worksheet.write(period_row, 0, 'Period {}'.format(p))
                period_row += 1

            for i in range(0, 5):
                worksheet.write(row, col, start_date_excel, date_format)
                worksheet.set_column(col, col, 18, justify_format)
                # checks if this is the first day of the week.
                if i == 0:
                    first_date_link_page = start_date_excel

                # sets for putting the information in the periods.
                period_row = 3

                # formats to a red column if no school that day.
                if start_date_excel in self.skip_days:
                    worksheet.write(2, col, 'No School', colour_format)
                    for h in range(0, period_number - 1):
                        worksheet.write(period_row, col, " ", colour_format)
                        period_row += 1
                        h += 1

                # formats cells to use a list provided by user.
                if start_date_excel not in self.skip_days:
                    period = 1

                    for j in range(0, period_number - 1):
                        if int(self.day_cycle.get()) == 1 or day > int(
                                self.day_cycle.get()):
                            day = 1

                        if self.schedule_day_full[day][period] == 'default':
                            if self.teach_names:
                                worksheet.data_validation(
                                    period_row - 1, col, period_row, col, {
                                        'validate': 'list',
                                        'source': [self.teach_names]
                                    })
                            period_row += 1
                            period += 1

                        else:
                            worksheet.write(
                                period_row - 1, col,
                                self.schedule_day_full[day][period])
                            period_row += 1
                            period += 1

                    if self.show_day_number_check.get() == 1:
                        worksheet.write(period_row, col, "Day {}".format(day))
                    day += 1

                # iterates variables
                col += 1
                start_date_excel += 1
                i += 1

                # Adds internal link so that you can navigate from the first page of the document.
                if i == 4:
                    second_date_link_page = start_date_excel
                    link_page.write_url(link_page_row, link_page_column,
                                        "internal:Week{}!A1".format(week),
                                        center_format, 'Week{}'.format(week))

                    link_page.write_rich_string(
                        link_page_row, link_page_column + 1, date_format,
                        '{}'.format(
                            self.regular_date(self, first_date_link_page)),
                        ' until ', date_format, '{}'.format(
                            self.regular_date(self, second_date_link_page)))
                    link_page_row += 1

            week += 1

            # adds link to first page with all the links to pages.
            worksheet.write_url('A12', "internal:'Link Page'!A1", bold_format,
                                "First Page")

            # creates new worksheet for the next week.
            worksheet = workbook.add_worksheet('Week{}'.format(week))

            # Adds two to account for the weekend.
            start_date_excel += 2

            r += 1

            # Resets variables for the next round. Because they need to be back in the same cells.
            row = 1
            col = 1
            period_row = 2

        link_page.activate()
        try:
            workbook.close()

        except PermissionError:
            messagebox.showinfo(
                message=
                'There has been an error. Try closing the excel spreadsheet and trying again.'
            )
            return 'None'
        messagebox.showinfo(message='Completed. Thank you!')
        self.client_exit()
예제 #13
0
class ReadBooks():
    def __init__(self, master):
        '''Creamos un layout general formado por etiquetas, campos de entrada, radiobutton, calendario (que por defecto especifica la fecha de hoy) y 3 botones.
        Uno para confirmar la fecha introducida en el calendario y los otros dos: guardar registro y mostrar registros.'''

        self.master = master
        master.title('LIBROS LEIDOS DE LA HEMEROTECA:')
        master.geometry('550x525+500+0')
        master.configure(bg='light slate grey')
        self.score = IntVar()

        self.l_customer = Label(master,
                                text='Introduce DNI de CLIENTE:',
                                bg='light slate grey',
                                fg='white').place(x=50, y=40)
        self.e_customer = Entry(master, width=20)
        self.e_customer.place(x=350, y=40)
        self.l_book = Label(master,
                            text='Introduce ISBN del Libro:',
                            bg='light slate grey',
                            fg='white').place(x=50, y=80)
        self.e_book = Entry(master, width=20)
        self.e_book.place(x=350, y=80)
        self.l_score = Label(
            master,
            text='Puntuacion sobre 10 que da el cliente a la pelicula:',
            bg='light slate grey',
            fg='white').place(x=50, y=120)
        self.l_score2 = Label(master,
                              text='(Clica un boton del 1 al 10)',
                              bg='light slate grey',
                              fg='white',
                              font=('Verdana', 7)).place(x=50, y=135)
        self.e_score = Entry(master, width=20)
        self.e_score.place(x=350, y=120)
        for i in range(1, 11):
            self.rb_score = Radiobutton(master,
                                        text='' + str(i),
                                        value=i,
                                        variable=self.score,
                                        command=self.get_score).place(
                                            x=(40 + 35 * i), y=160)

        self.calendar = Calendar(master,
                                 selectmode='day',
                                 year=date.today().year,
                                 month=date.today().month,
                                 day=date.today().day)
        self.calendar.place(x=250, y=200)

        self.b_selectiondate = Button(master,
                                      text='Confirma fecha de lectura',
                                      bd=5,
                                      command=self.write_date).place(x=50,
                                                                     y=250)

        self.b_save = Button(master,
                             text='Guardar datos',
                             bd=5,
                             command=self.save).place(x=50, y=350)
        self.b_show = Button(master,
                             text='Mostrar datos',
                             bd=5,
                             command=self.show).place(x=350, y=400)

    def save(self):
        ''' Creamos la conexion con la bbdd. Creamos una tabla donde la clave primaria es compuesta y esta formada por 2 ajenas una de cada tabla:
        libros y clientes. Debemos activar las claves ajenas con PRAGMA no solo en la tabla hija sino en cada una de las conexiones de las tablas padre.
        Restringimos las claves foraneas a la modificacion o eliminacion en casacada desde las tablas padre.
        Recogemos los valores del registro introducido por el usuario y los introducimos en la tabla siempre que la fecha no sea posterior al dia de hoy.
        Borramos los campos de entrada creados por el usuario.
        Creamos una excepcion si las claves ajenas (DNI y ISBN) introducidas por el usuario, no existen. O si esas claves ajenas,
        que es la primaria de esta tabla, ya han sido introducidas (mismo libro y mismo cliente).
        '''
        try:
            c = sqlite3.connect('Hemeroteca.db')
            cursor = c.cursor()
            cursor.execute('PRAGMA foreign_keys=ON')
            #cursor.execute ('DROP TABLE LibrosLeidos')
            cursor.execute(
                '''CREATE TABLE IF NOT EXISTS LibrosLeidos (DNI_Cliente INTEGER,
                ISBN_Libro INTEGER , Puntuacion INTEGER, Fecha TEXT,
                PRIMARY KEY(DNI_Cliente, ISBN_Libro),
                FOREIGN KEY (DNI_Cliente) REFERENCES Clientes(DNI) ON UPDATE CASCADE ON DELETE CASCADE ,
                FOREIGN KEY(ISBN_Libro) REFERENCES Libros(ISBN) ON UPDATE CASCADE ON DELETE CASCADE)'''
            )

            if ((datetime.strptime(self.calendar.get_date(),
                                   '%m/%d/%y').date()) <= date.today()):

                cursor.execute(
                    '''INSERT INTO LibrosLeidos ( DNI_Cliente,
                            ISBN_Libro, Puntuacion, Fecha) VALUES (?,?,?,?)''',
                    (self.e_customer.get(), self.e_book.get(),
                     self.score.get(), self.calendar.get_date()))

                self.e_customer.delete(0, END)
                self.e_book.delete(0, END)
                self.e_score.delete(0, END)
                self.calendar_label = Label(self.master,
                                            text='                  ',
                                            bg='light slate grey',
                                            fg='white').place(x=100, y=300)

                c.commit()
                c.close()
            else:
                showwarning(
                    title='CUIDADO!',
                    message='Debes introducir una fecha anterior a hoy o hoy')

        except Exception as excep:
            showerror(
                title='SE HA PRODUCIDO UN  ERROR',
                message='Ese cliente con ese mismo libro ya existen. ' + '\n' +
                'O bien, estas introduciendo un cliente o un libro inexistentes'
            )

    def show(self):
        '''Volvemos a crear la conexion. Seleccionamos todos los registros de la tabla creada y
        les recogemos en una etiqueta separados por salto de linea. Recogemos la excepcion si la tabla esta todavia vacia. '''
        try:
            connection = sqlite3.connect('Hemeroteca.db')
            cursor = connection.cursor()
            cursor.execute('PRAGMA foreign_keys=ON')
            cursor.execute('SELECT * FROM LibrosLeidos')
            records = cursor.fetchall()
            print(records)
            print_records = ''

            for record in records:
                print_records += str(record) + '\n'

            self.records_label = Label(self.master,
                                       text=print_records,
                                       font=('Helvetica', 10),
                                       bg='light slate grey',
                                       fg='white').place(x=50, y=400)

            connection.commit()
            connection.close()
        except Exception as warning:
            showwarning(
                title='ATENCION',
                message=
                'Todavia no has introducido la preferencia de ningun cliente por ningun libro'
            )

    def get_score(self):
        '''Rellenamos el campo de entrada de puntuacion automaticamente con la seleccion de puntuacion presionando el radiobutton por el usuario.'''
        self.e_score.delete(0, END)
        self.e_score.insert(0, self.score.get())

    def write_date(self):
        '''Creamos una etiqueta que recoja la fecha escrita seleccionada por el usuario al pulsar en el calendario.  '''
        self.calendar_label = Label(self.master,
                                    text=self.calendar.get_date() + '   ',
                                    bg='light slate grey',
                                    fg='white').place(x=100, y=300)
예제 #14
0
class MainWindow(Frame):
    def __init__(self, master, email):
        super().__init__(master)
        self.email = email
        self.pack()

        load = Image.open("oneclicklogo.png")
        render = ImageTk.PhotoImage(load)
        self.img = Label(self.master, image=render, bg='midnight blue')
        self.img.image = render
        self.img.place(x=300, y=40)

        self.frame = Frame(master, width=240, height=720, bg='DarkGoldenrod1')
        self.frame.pack(side=LEFT, fill=BOTH)
        self.add_button = Button(self.frame, text='Make Appointment', font='verdana 16 bold', fg='midnight blue',
                                 command=self.create_event)
        self.event_frame = Frame(master, width=240, height=720, bg='DarkGoldenrod1')
        self.event_frame.pack(side=RIGHT, fill=BOTH)
        self.event_canvas = Canvas(self.event_frame, bg='DarkGoldenrod1')
        self.event_canvas.pack(side=LEFT, fill=BOTH)
        self.scroll = Scrollbar(self.event_frame, bg='DarkGoldenrod1', orient=VERTICAL,
                                    command=self.event_canvas.yview)
        self.scroll.pack(side=LEFT, fill=Y)
        self.event_canvas.configure(yscrollcommand=self.scroll.set)
        self.event_canvas.bind('<Configure>',
                               lambda e: self.event_canvas.configure(scrollregion=self.event_canvas.bbox("all")))
        self.inner_frame = Frame(self.event_canvas, bg='DarkGoldenrod1')
        self.event_canvas.create_window((0, 0), window=self.inner_frame, anchor="ne")

        self.variable = StringVar(self.event_frame)
        self.my_events_label = Label(self.inner_frame, text="My Events", bg='lightblue', font='verdana 16 bold', padx=1,
                                     pady=1)

        # self.event_one_label = Label(self.event_frame, text="Event One", bg='lightpink', font='bold', padx=20, pady=20)

        def dynamic_delete(event_name):
            usersDatabase.delete_user_event(self.email, event_name)
            self.master.destroy()
            self.master = Tk()
            self.master.title('OneClick')
            self.master.geometry('1280x720')
            self.master.configure(bg='midnight blue')
            app = MainWindow(self.master, email)

        def up_event_clicked(event_name, tup):

            chosen = self.option()
            # self.master.destroy()
            self.new_root = Tk()
            title = 'Enter new ' + chosen
            if chosen == 'Date':
                title = 'Enter new date in mm/dd/yy format'
            if chosen == 'Start Time':
                title = 'Enter new start time in hh:mm format'
            if chosen == 'End Time':
                title = 'Enter new end time in hh:mm format'
            self.new_root.title(title)
            self.new_root.geometry('500x500')
            self.new_root.configure(bg='DarkGoldenrod1')
            UpdateWindow(self.new_root, email, event_name, tup, chosen)

        def refresh():
            event_dict = usersDatabase.get_user_events(self.email)
            #   for widget in self.event_frame.winfo_children():
            #      widget.destroy()
            self.my_events_label.pack()
            # self.event_one_label.pack()

            for key in event_dict:
                tup = event_dict[key]
                size = len(tup)
                dat = tup[2].strftime('%m %d %Y')
                str_date = dat.split(' ')
                new_date = str_date[0] + '/' + str_date[1] + '/' + str_date[2]
                info = key + '\n' + 'Description:' + tup[1] + '\n' + 'Zoom Link:' + tup[
                    0] + '\n' + 'Date:' + new_date + '\n' + 'Start Time:' + str(tup[3]) + '\n' + 'End Time:' + str(
                    tup[4])
                self.pass_tuple = (key, tup[1], tup[0], tup[2], tup[3], tup[4])
                option_list = ['Event Name', 'Zoom Link', 'Description', 'Date', 'Start Time', 'End Time']
                # self.variable = StringVar(self.event_frame)
                print(type(tup[3]))
                print(str(tup[3]))

                def is_completed():
                    stime_str = str(tup[3]).split(':')
                    etime_str = str(tup[4]).split(':')
                    now_str = datetime.datetime.now().strftime('%H %M').split(' ')
                    d = datetime.date.today()
                    today_str_date = d.strftime('%m %d %Y').split(' ')

                    print(str_date[2] + ', ' + today_str_date[2])

                    if ((int(str_date[1]) == int(today_str_date[1])) and (
                            int(str_date[2]) == int(today_str_date[2])) and (
                            int(str_date[0]) == int(today_str_date[0]))):
                        if (int(etime_str[0]) < int(now_str[0])):
                            return 'brown'
                        if ((int(etime_str[1]) < int(now_str[1]) and (int(etime_str[0]) == int(now_str[0])))):
                            return 'brown'
                        if (int(stime_str[0]) < int(now_str[0])):
                            print('yes4')
                            return 'green'
                        elif ((int(stime_str[1]) <= int(now_str[1])) and (int(stime_str[0]) == int(now_str[0]))):
                            print(stime_str[1] + ', ' + now_str[1])
                            print('yes5')
                            return 'green'
                        else:
                            return 'red'

                    elif (int(str_date[2]) < int(today_str_date[2])):
                        return 'brown'
                    elif ((int(str_date[2]) == int(today_str_date[2])) and (int(str_date[0]) < int(today_str_date[0]))):
                        return 'brown'
                    elif ((int(str_date[2]) == int(today_str_date[2])) and (
                            int(str_date[0]) == int(today_str_date[0])) and (
                                  int(str_date[1]) < int(today_str_date[1]))):
                        return 'brown'

                    else:
                        if (int(str_date[2]) > int(today_str_date[2])):
                            return 'red'
                        if (int(str_date[2]) < int(today_str_date[2])):
                            print('yes1')
                            return 'green'
                        elif ((int(str_date[0]) < int(today_str_date[0])) and (
                                int(str_date[2]) == int(today_str_date[2]))):
                            print('yes2')
                            return 'green'
                        elif ((int(str_date[1]) < int(today_str_date[1])) and (
                                int(str_date[2]) == int(today_str_date[2])) and (
                                      int(str_date[0]) == int(today_str_date[0]))):
                            print('yes3')
                            return 'green'
                        else:
                            return 'red'

                self.event = Label(self.inner_frame, text=info, bg='lightpink', font='bold', padx=15, pady=20)

                if (is_completed() == 'green'):
                    self.event = Label(self.inner_frame, text=info, bg='green3', font='verdana 12', padx=15, pady=20)
                elif (is_completed() == 'brown'):
                    self.event = Label(self.inner_frame, text=info, bg='light pink', font='verdana 12', padx=15,
                                       pady=20)
                else:
                    self.event = Label(self.inner_frame, text=info, bg='MediumOrchid1', font='verdana 12', padx=15,
                                       pady=20)

                self.event.pack()
                self.variable.set(option_list[0])
                self.variable.trace("w", self.option)
                self.update_options = OptionMenu(self.inner_frame, self.variable, *option_list)
                self.update_options.pack()
                self.update_button = Button(self.inner_frame, text='Update', font='veranda 14 bold', fg='midnight blue',
                                            command=lambda i=key, j=self.pass_tuple: up_event_clicked(i, j))
                self.update_button.pack()
                self.del_button = Button(self.inner_frame, text='Delete', font='veranda 14 bold', fg='midnight blue',
                                         command=lambda i=key: dynamic_delete(i))
                self.del_button.pack()

        ref_func = refresh()

        self.logout_button = Button(self.frame, text='Logout', font='verdana 16 bold', fg='midnight blue',
                                    command=self.logout)
        self.add_button.pack()
        self.logout_button.pack()

    def option(self, *args):
        return self.variable.get()

    def logout(self):
        self.master.destroy()
        new_root = Tk()
        new_root.title('OneClick - Login')
        new_root.configure(bg='DarkGoldenrod1')
        new_root.geometry('1000x1000')
        lw = LoginWindow(new_root)
        new_root.mainloop()

    def create_event(self):

        # TODO: use grid and create spacing between widgets in self.frame, also place submit button in the bottom-middle

        self.logout_button.destroy()
        self.new_logout_button = Button(self.frame, text='Logout', font='verdana 14 bold', fg='midnight blue',
                                        command=self.logout)
        self.add_button.pack_forget()
        self.calendar = Calendar(self.frame, font='Arial 14', bg='midnight blue', fg='midnight blue', cursor='dotbox',
                                 selectmode='day',
                                 showothermonthdays=False, showweeknumbers=False, firstweekday='sunday')
        self.label_event = Label(self.frame, text='Event Name', font='veranda 14 bold', bg='DarkGoldenrod1',
                                 fg='midnight blue')
        self.label_descr = Label(self.frame, text='Description', font='veranda 14 bold', bg='DarkGoldenrod1',
                                 fg='midnight blue')
        self.label_command = Label(self.frame, text='Application Selection', font='veranda 14 bold',
                                   bg='DarkGoldenrod1', fg='midnight blue')
        self.label_link = Label(self.frame, text='Zoom Link', font='veranda 14 bold', bg='DarkGoldenrod1',
                                fg='midnight blue')

        self.entry_event = Entry(self.frame, width=64)
        self.entry_descr = Text(self.frame, width=48, height=5)
        self.entry_link = Entry(self.frame, width=64)

        self.calendar.pack()
        self.label_event.pack(padx=20)
        self.entry_event.pack(padx=20)
        self.label_descr.pack(padx=20)
        self.entry_descr.pack(padx=20)
        self.label_link.pack(padx=20)
        self.entry_link.pack(padx=20)

        self.start_label = Label(self.frame, text='Start Time: ', bg='DarkGoldenrod1', font='veranda 14 bold',
                                 fg='midnight blue')
        self.start_label.place(x=20, y=450)
        self.start_hourstr = StringVar(self.frame, '10')
        self.start_hour = Spinbox(self.frame, font='veranda 14 bold', fg='midnight blue', from_=0, to=23, wrap=True,
                                  textvariable=self.start_hourstr, width=2,
                                  state="readonly")
        self.start_minstr = StringVar(self.frame, '30')
        self.start_minstr.trace("w", self.trace_var)
        self.start_last_value = ""
        self.start_min = Spinbox(self.frame, font='veranda 14 bold', fg='midnight blue', from_=0, to=59, wrap=True,
                                 textvariable=self.start_minstr, width=2,
                                 state="readonly")
        self.start_hour.place(x=133, y=450)
        self.start_min.place(x=173, y=450)

        self.end_label = Label(self.frame, text='End Time: ', bg='DarkGoldenrod1', font='veranda 14 bold',
                               fg='midnight blue')
        self.end_label.place(x=220, y=450)
        self.end_hourstr = StringVar(self.frame, '10')
        self.end_hour = Spinbox(self.frame, font='veranda 14 bold', fg='midnight blue', from_=0, to=23, wrap=True,
                                textvariable=self.end_hourstr, width=2,
                                state="readonly")
        self.end_minstr = StringVar(self.frame, '30')
        self.end_minstr.trace("w", self.trace_var)
        self.end_last_value = ""
        self.end_min = Spinbox(self.frame, font='veranda 14 bold', fg='midnight blue', from_=0, to=59, wrap=True,
                               textvariable=self.end_minstr, width=2,
                               state="readonly")
        self.end_hour.place(x=326, y=450)
        self.end_min.place(x=366, y=450)

        def time_date_str(hour, minute):
            min_str = lambda min: "0" + min if int(min) < 10 else min
            minute = min_str(minute)
            return self.calendar.get_date() + f"/{hour}" + f"/{minute}"

        def check_conflict():
            event_dict = usersDatabase.get_user_events(self.email)
            #   for widget in self.event_frame.winfo_children():
            #      widget.destroy()
            self.my_events_label.pack()
            # self.event_one_label.pack()

            for key in event_dict:
                tup = event_dict[key]
                size = len(tup)
                dat = tup[2].strftime('%m %d %Y')
                print('$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
                print(type(tup[2]))
                print('$$$$$$$$$$$$$$$$$$$$$$$$$$$$$')
                if(tup[2] == self.give_date(self.calendar.get_date())):
                    st_time = time(int(self.start_hourstr.get()), int(self.start_minstr.get()))
                    end_time = time(int(self.end_hourstr.get()), int(self.end_minstr.get()))
                    est_time = (datetime.datetime.min + tup[3]).time()
                    eend_time = (datetime.datetime.min + tup[4]).time()
                    print(est_time)
                    print(st_time)
                    print(end_time)
                    if ((st_time >= est_time) and (st_time <= eend_time)):
                        print('here1')
                        return str(key)
                    elif ((end_time >= est_time) and (end_time <= eend_time)):
                        print('here2')
                        return str(key)
                    elif ((st_time >= est_time) and (end_time <= eend_time)):
                        print('here3')
                        return str(key)
                    elif ((st_time <= est_time) and (est_time <= end_time)):
                        print('here4')
                        return str(key)
                    

            return None


        def run():
            eventscheduler.run_popup(
                time_date_str(
                    self.start_hourstr.get(),
                    self.start_minstr.get()
                )
                ,
                self.entry_event.get(),
                self.entry_descr.get("1.0", "end-1c"),
                self.entry_link.get()
            )
            ret_val = check_conflict()
            if(not(ret_val == None)):
                print('Yes there is a conflict -- returning now!')
                self.error_text.set('Unable to create event, conflict with:{}'.format(ret_val))
                self.error_label.configure(bg='red')
                return
            else:
                self.submit_event()

        self.submit_btn = Button(self.frame, text='Submit', font='veranda 14 bold', fg='midnight blue', command=run)
        self.error_text = StringVar()
        self.error_text.set("")
        self.error_label = Label(self.master, textvariable=self.error_text, bg='DarkGoldenrod1', font='veranda 15 bold')
        self.submit_btn.place(x=230, y=490)
        self.new_logout_button.place(x=0, y=0)
        self.error_label.place(x=80, y=530)

    def trace_var(self, *args):
        if self.start_last_value == "59" and self.start_minstr.get() == "0":
            self.start_hourstr.set(int(self.start_hourstr.get()) + 1 if self.start_hourstr.get() != "23" else 0)
        self.start_last_value = self.start_minstr.get()

    def recurring(self):
        # Make a checkbar with every day of the week
        self.pack()

    def submit_event(self):
        import eventscheduler

        #    if not usersDatabase.check_overlap(self.email, self.give_date(self.calendar.get_date()), time(int(self.start_hourstr.get()), int(self.start_minstr.get())), time(int(self.end_hourstr.get()), int(self.end_minstr.get()))):
        #       pass

        #    print(type(self.start_hourstr.get()))
        #   print(type(self.start_minstr.get()))
        #   print(self.calendar.get_date())

        # exit(-1)
        start_time = self.start_hourstr.get() + ":" + self.start_minstr.get() + ":" + "00"
        end_time = self.end_hourstr.get() + ":" + self.end_minstr.get() + ":" + "00"
        
        
        usersDatabase.add_user_info(self.email, self.entry_event.get(), self.entry_link.get(),
                                    self.entry_descr.get('1.0', 'end-1c'),

                                    self.give_date(self.calendar.get_date()),
                                    time(int(self.start_hourstr.get()), int(self.start_minstr.get())),
                                    time(int(self.end_hourstr.get()), int(self.end_minstr.get())))
        self.master.destroy()
        self.master = Tk()
        self.master.title('OneClick')
        self.master.geometry('1280x720')
        self.master.configure(bg='midnight blue')
        app = MainWindow(self.master, self.email)

    def display_event(self):
        self.r_frame = Frame(self, bg='lightblue').pack(side=RIGHT)
        event = Label(self.r_frame, text='Event: \n' + self.entry_event.get()).pack()
        desc = Label(self.r_frame, text='Description: \n' + self.entry_descr.get('1.0', 'end-1c')).pack()
        link = Label(self.r_frame, text='Link: \n' + self.entry_link.get()).pack()
        times = Label(self.r_frame,
                      text='Start Time: ' + self.start_hourstr.get() + ':' + self.start_minstr.get() + ' End Time: ' + self.end_hourstr.get() + ':' + self.end_minstr.get()).pack()

    def give_time(self, time_str):
        # converts the string to a datetime object

        split_time = time_str.split(":")
        split_time_2 = []
        if (split_time[1][2] == "A"):
            time_str_2 = split_time[1].split("A")[0]
            return time(int(split_time[0]), int(time_str_2))
        else:
            time_str_2 = split_time[1].split("P")[0]
            return time(int(split_time[0]), int(time_str_2))

    def give_date(self, date_str):
        split_date = date_str.split("/")
        return datetime.date(int("20" + split_date[2]), int(split_date[0]), int(split_date[1]))
예제 #15
0
to_up2_ = to_up2.get()

en_up3_ = en_up3.get()

enter_name_up4_ = enter_name_up4.get()

#insert final data
eventName = en_up3_

fromHour = from_up1_

toHour = to_up2_

enterName = enter_name_up4_

calendarSelect = cal.get_date()

#date confirmation
date = Label(root, text="")
date.grid(row=9, column=1)
#forms
lbl3 = Label(root, text='Event Name:').grid(row=4, column=0)
e3 = Entry(root, bd=5, textvariable=en_up3).grid(row=4, column=1)

lbl1 = Label(root, text='FROM:').grid(row=5, column=0)
e = Entry(root, bd=5, textvariable=from_up1).grid(row=5, column=1)

lbl2 = Label(root, text='TO:').grid(row=6, column=0)
e1 = Entry(root, bd=5, textvariable=to_up2).grid(row=6, column=1)

lbl4 = Label(root, text='Enter your Name:').grid(row=7, column=0)
예제 #16
0
파일: Vista.py 프로젝트: berrio97/TFG_NBA
class Vista(Frame):
    # Inicializa el controlador y algunas variables globales
    # Params:
    #   master: instancia de Window
    #   modelo: Modelo
    def __init__(self, master, modelo):
        Frame.__init__(self, master)
        self.pack()
        self.master = master
        self.modelo = modelo
        self.controlador = Controlador(self.modelo, self)
        self.col1 = 'khaki1'
        self.col2 = 'snow'
        self.font = 'Helvetica'
        self.init_components()
        return

    #Inicializa los componentes de la Vista y los coloca
    def init_components(self):
        self.label_model = Label(self.master,
                                 text='Modelo',
                                 font=(self.font, 14),
                                 relief=GROOVE,
                                 bg=self.col2)
        self.label_data = Label(self.master,
                                text='Datos',
                                font=(self.font, 14),
                                relief=GROOVE,
                                bg=self.col2)
        self.label_pred = Label(self.master,
                                text='Predicción',
                                font=(self.font, 14),
                                relief=GROOVE,
                                bg=self.col2)
        self.label_res = Label(self.master,
                               text='Resultados',
                               font=(self.font, 14),
                               relief=GROOVE,
                               bg=self.col2)

        self.variable = StringVar()
        self.variable.set('Modelo 1')
        self.variable.trace("w", self.change_model)

        self.model_selector = OptionMenu(self.master, self.variable,
                                         *list(self.modelo.modelos.keys()))

        self.frame = Frame(self.master)

        self.alg_label = Label(self.frame,
                               text='Algoritmo',
                               font=(self.font, 8, 'bold'),
                               bg=self.col2,
                               relief='raised',
                               width=20)
        self.seas_label = Label(self.frame,
                                text='Temporadas',
                                font=(self.font, 8, 'bold'),
                                bg=self.col2,
                                relief='raised',
                                width=20)
        self.columns_label = Label(self.frame,
                                   text='Selección columnas',
                                   font=(self.font, 8, 'bold'),
                                   bg=self.col2,
                                   relief='raised',
                                   width=20)
        self.pca_label = Label(self.frame,
                               text='PCA',
                               font=(self.font, 8, 'bold'),
                               bg=self.col2,
                               relief='raised',
                               width=20)
        self.params_label = Label(self.frame,
                                  text='Parámetros',
                                  bg=self.col2,
                                  font=(self.font, 8, 'bold'),
                                  relief='raised',
                                  width=20)

        self.alg_value = Label(self.frame,
                               text='',
                               font=(self.font, 8),
                               bg=self.col2,
                               relief='raised',
                               width=30)
        self.seas_value = Label(self.frame,
                                text='',
                                font=(self.font, 8),
                                bg=self.col2,
                                relief='raised',
                                width=30)
        self.columns_value = Label(self.frame,
                                   text='',
                                   font=(self.font, 8),
                                   bg=self.col2,
                                   relief='raised',
                                   width=30)
        self.pca_value = Label(self.frame,
                               text='',
                               font=(self.font, 8),
                               bg=self.col2,
                               relief='raised',
                               width=30)
        self.params_value = Label(self.frame,
                                  text='',
                                  font=(self.font, 8),
                                  bg=self.col2,
                                  relief='raised',
                                  width=30)

        self.load_model_but = Button(self.master,
                                     text='Cargar modelo',
                                     state='disabled',
                                     command=self.load_model,
                                     bg=self.col2)

        self.train_model_but = Button(self.master,
                                      text='Entrenar modelo',
                                      state='disabled',
                                      command=self.train_model,
                                      bg=self.col2)

        self.load_data_but = Button(self.master,
                                    text='Cargar datos',
                                    command=self.load_data,
                                    bg=self.col2)

        self.ref_but = Button(self.master,
                              text='Actualizar datos',
                              command=self.refresh,
                              bg=self.col2)

        self.home_label = Label(self.master, text='Equipo local', bg=self.col1)
        self.away_label = Label(self.master,
                                text='Equipo visitante',
                                bg=self.col1)

        self.home = StringVar()
        self.home.set(self.modelo.teams[0])
        self.homeOptionMenu = OptionMenu(self.master, self.home,
                                         *list(self.modelo.teams))
        self.homeOptionMenu.config(state='disabled')

        self.away = StringVar()
        self.away.set(self.modelo.teams[0])
        self.awayOptionMenu = OptionMenu(self.master, self.away,
                                         *list(self.modelo.teams))
        self.awayOptionMenu.config(state='disabled')

        self.calendar = Calendar(self.master, state='disabled')

        self.pred_but = Button(self.master,
                               text='Hallar predicciones',
                               state='disabled',
                               command=self.exec_prediction,
                               bg=self.col2)

        self.result = Label(self.master,
                            text='',
                            bg=self.col1,
                            font=(self.font, 10, 'bold'))
        self.pred = Label(self.master,
                          text='',
                          bg=self.col1,
                          font=(self.font, 10, 'bold'))
        self.team_win = Label(self.master,
                              text='',
                              bg=self.col1,
                              font=(self.font, 10, 'bold'))

        self.sep1 = Separator(self.master, orient=HORIZONTAL)
        self.sep2 = Separator(self.master, orient=HORIZONTAL)
        self.sep3 = Separator(self.master, orient=VERTICAL)

        self.label_error = Label(self.master,
                                 text='',
                                 font=('device', 10),
                                 fg='red',
                                 bg=self.col1)

        ### PACKING & PLACING
        self.label_model.pack()
        self.label_model.place(relx=0.05, rely=0.05, anchor=W)
        self.label_data.pack()
        self.label_data.place(relx=0.05, rely=0.4, anchor=W)
        self.label_pred.pack()
        self.label_pred.place(relx=0.05, rely=0.6, anchor=W)

        self.model_selector.pack()
        self.model_selector.place(relx=0.15, rely=0.15, anchor=CENTER)

        self.frame.pack()
        self.frame.place(relx=0.25, rely=0.05)

        self.alg_label.grid(row=0, rowspan=1, column=0, columnspan=1)
        self.seas_label.grid(row=1, rowspan=1, column=0, columnspan=1)
        self.columns_label.grid(row=2, rowspan=1, column=0, columnspan=1)
        self.pca_label.grid(row=3, rowspan=1, column=0, columnspan=1)
        self.params_label.grid(row=4,
                               rowspan=1,
                               column=0,
                               columnspan=1,
                               sticky=N + E + S + W)

        self.alg_value.grid(row=0, rowspan=1, column=1, columnspan=1)
        self.seas_value.grid(row=1, rowspan=1, column=1, columnspan=1)
        self.columns_value.grid(row=2, rowspan=1, column=1, columnspan=1)
        self.pca_value.grid(row=3, rowspan=1, column=1, columnspan=1)
        self.params_value.grid(row=4, rowspan=1, column=1, columnspan=1)
        self.change_model()

        self.load_model_but.pack()
        self.load_model_but.place(relx=0.1, rely=0.48, anchor=CENTER)

        self.train_model_but.pack()
        self.train_model_but.place(relx=0.24, rely=0.48, anchor=CENTER)

        self.load_data_but.pack()
        self.load_data_but.place(relx=0.38, rely=0.48, anchor=CENTER)

        self.ref_but.pack()
        self.ref_but.place(relx=0.52, rely=0.48, anchor=CENTER)

        self.home_label.pack()
        self.home_label.place(relx=0.1, rely=0.7, anchor=CENTER)

        self.away_label.pack()
        self.away_label.place(relx=0.25, rely=0.7, anchor=CENTER)

        self.homeOptionMenu.pack()
        self.homeOptionMenu.place(relx=0.1, rely=0.75, anchor=CENTER)

        self.awayOptionMenu.pack()
        self.awayOptionMenu.place(relx=0.25, rely=0.75, anchor=CENTER)

        self.calendar.pack()
        self.calendar.place(relx=0.45, rely=0.75, anchor=CENTER)

        self.pred_but.pack()
        self.pred_but.place(relx=0.17, rely=0.82, anchor=CENTER)

        self.label_res.pack()
        self.label_res.place(relx=0.7, rely=0.05, anchor=CENTER)

        self.result.pack()
        self.result.place(relx=0.8, rely=0.15, anchor=CENTER)

        self.pred.pack()
        self.pred.place(relx=0.8, rely=0.85, anchor=CENTER)

        self.team_win.pack()
        self.team_win.place(relx=0.8, rely=0.89, anchor=CENTER)

        self.sep1.place(relx=0.05, rely=0.33, relwidth=0.55)
        self.sep2.place(relx=0.05, rely=0.53, relwidth=0.55)
        self.sep3.place(relx=0.61, rely=0.05, relheight=0.9)

        self.label_error.place(relx=0.8, rely=0.93, anchor=CENTER)

    # Evento de cambiar el modelo que se esta seleccionando
    def change_model(self, *args):
        self.controlador.evento_change_model()
        if self.modelo.model_read is not None:
            self.alg_value['text'] = self.modelo.algorithms[
                self.modelo.model_read.alg]
            if self.modelo.model_read.seasons == '2015':
                seas = 'Desde 2014/2015'
            elif self.modelo.model_read.seasons == '2005':
                seas = 'Desde 2004/2005'
            else:
                seas = 'Desde 2000/2001'
            self.seas_value['text'] = seas
            self.columns_value['text'] = self.modelo.model_read.col
            self.pca_value[
                'text'] = 'Sí' if self.modelo.model_read.pca_analysis else 'No'

            if not pd.isnull(self.modelo.model_read.params):
                aux = ''
                for key in list(eval(self.modelo.model_read.params).keys()):
                    aux += str(key) + ': ' + str(
                        eval(self.modelo.model_read.params)[key]) + '\n'
                self.params_value['text'] = aux[:-1]
            else:
                self.params_value['text'] = ''

    # Evento de cargar los datos de los partidos
    def load_data(self):
        self.controlador.evento_load()
        if self.modelo.file is not None:
            self.load_model_but['state'] = 'active'
            self.calendar['state'] = 'normal'
            self.label_error.config(fg='green')
            self.label_error['text'] = 'Datos cargados con éxito'

    # Evento de actualizar los datos
    def refresh(self):
        self.controlador.evento_refresh()
        self.load_data()
        self.label_error.config(fg='green')
        self.label_error['text'] = 'Datos actualizados con éxito'

    # Evento de cargar el modelo predictivo seleccionado
    def load_model(self):
        self.label_error['text'] = ''
        self.train_model_but['state'] = 'active'
        self.controlador.evento_load_model()
        performance = self.modelo.modelo_prediccion.ac
        self.result['text'] = 'TASA DE ACIERTO: ' + str(
            performance.round(4) * 100) + '%'
        self.roc()
        self.pred_but['state'] = 'active'
        self.homeOptionMenu.config(state='active')
        self.awayOptionMenu.config(state='active')
        self.label_error.config(fg='green')
        self.label_error['text'] = 'Modelo cargado con éxito'

    # Evento de entrenar el modelo predictivo seleccionado
    def train_model(self):
        self.label_error['text'] = ''
        self.controlador.evento_train_model()
        self.load_model()

    # Evento de crear una curva ROC sobre los resultados del modelo predictivo seleccionado
    def roc(self):
        fpr, tpr, thres = roc_curve(self.modelo.modelo_prediccion.Y_test,
                                    self.modelo.modelo_prediccion.scores)
        auc_roc = auc(fpr, tpr)

        fig = Figure(figsize=(3.2, 3.2))
        a = fig.add_subplot(111)
        a.plot(fpr, tpr, color='blue', label='AUC %0.2f' % auc_roc)
        a.legend(loc="lower right")

        a.set_position([0.15, 0.12, 0.8, 0.8])
        a.set_xticks(ticks=np.arange(0, 1.5, 0.5))
        a.set_yticks(ticks=np.arange(0, 1.5, 0.5))
        a.set_xticklabels(labels=np.arange(0, 1.5, 0.5),
                          fontdict={'fontsize': 8})
        a.set_yticklabels(labels=np.arange(0, 1.5, 0.5),
                          fontdict={'fontsize': 8})
        a.set_title("Curva ROC " +
                    self.modelo.algorithms[self.modelo.model_read.alg],
                    fontsize=10)
        a.set_ylabel("TPR", fontsize=8)
        a.set_xlabel("FPR", fontsize=8)

        canvas = FigureCanvasTkAgg(fig, master=self.master)
        canvas.get_tk_widget().pack(expand=True)
        canvas.get_tk_widget().place(relx=0.8, rely=0.5, anchor=CENTER)
        canvas.draw()

    # Evento de crear las predicciones para un partido determinado
    def exec_prediction(self):
        date = datetime.strptime(self.calendar.get_date(), '%m/%d/%y')
        game_id = str(
            date.year
        ) + '%02d' % date.month + '%02d' % date.day + '0' + self.home.get()

        if self.home.get() != self.away.get() and self.home.get(
        ) != 'No seleccionado' and self.away.get() != 'No seleccionado':
            aux = self.modelo.modelo_prediccion.predictions_test
            game_true = game_id in aux.game_id.values
            if date < datetime.today() and game_true and aux[
                    aux.game_id == game_id]['a_team_id'].values[
                        0] == self.away.get() or date > datetime.today():
                self.controlador.evento_exec_prediction()
                predres = self.modelo.prediction
                aux = self.home.get() if predres else self.away.get()
                self.label_error['text'] = ''
                self.pred['text'] = str(self.home.get()) + ': ' + str(
                    predres.round(2)) + '\t' + str(
                        self.away.get()) + ': ' + str((1 - predres).round(2))
                if date < datetime.today():
                    self.team_win['text'] = 'Victoria real: ' + str(aux)
            else:
                self.label_error.config(fg='red')
                self.label_error[
                    'text'] = 'ERROR: Ese partido no se ha disputado.'
                self.pred['text'] = ''
                self.team_win['text'] = ''
        elif self.home.get() == 'No seleccionado' and self.away.get(
        ) == 'No seleccionado':
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error['text'] = 'ERROR: Hay que determinar los equipos'
        elif self.home.get() == 'No seleccionado' or self.away.get(
        ) == 'No seleccionado':
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error['text'] = 'ERROR: Falta un equipo por determinar'
        elif self.home.get() == self.away.get():
            self.label_error.config(fg='red')
            self.pred['text'] = ''
            self.team_win['text'] = ''
            self.label_error[
                'text'] = 'ERROR: Los equipos deben ser diferentes.'
예제 #17
0
class Notatnik():

    def __init__(self, master, width, height):
        self.master = master
        self.master.geometry("%sx%s+100+100" % (width, height))
        self.master.title("Notatnik")

        self.btn = Button(master, bg="lightblue", text="DODAJ NOTATKĘ", font=(
            'Calibri Light', 20), command=self.new_note)
        self.btn.pack(fill=BOTH, expand=1)

        self.btn2 = Button(master, bg="lightblue",
                           text="ODCZYTAJ NOTATKĘ", font=('Calibri Light', 20), command=self.odczytaj)
        self.btn2.pack(fill=BOTH, expand=1)

        self.c = conn.cursor()
        self.c.execute('''CREATE VIRTUAL TABLE IF NOT EXISTS notatki USING FTS5
             (data, nazwa, notatka)''')

    def new_note(self):
        self.newWindow = tk.Toplevel(self.master)
        self.dodtyt = tk.Label(
            self.newWindow, text="DODAJ TYTUŁ", font=('Calibri Light', 15))
        self.dodtyt.grid(column=0, row=0)
        self.tytul = tk.Entry(self.newWindow, width=40)
        self.tytul.grid(column=1, row=0)
        self.textfield = tkscrolled.ScrolledText(self.newWindow)
        self.textfield.grid(columnspan=2)
        self.addButton = Button(
            self.newWindow, text="Dodaj!", command=self.dodaj)
        self.addButton.grid(columnspan=2)

    def searchDatabase(self, searchQuery):
        self.c.execute(
            '''SELECT * FROM notatki WHERE nazwa = ? COLLATE NOCASE''', (searchQuery,))
        self.searchResult = self.c.fetchall()
        conn.commit()
        print(searchQuery)
        print(self.searchResult)
        return self.searchResult

    def odczytaj(self):
        self.newWindow1 = tk.Toplevel(self.master)
        self.ramka1 = tk.Frame(self.newWindow1, bg='blue', bd=2)
        self.ramka1.grid()
        self.szukajd = tk.Label(
            self.ramka1, text="SZUKAJ PO DACIE", font=('Calibri Light', 15))
        self.szukajd.grid(column=0, row=0)
        self.szukajde = Calendar(self.ramka1)
        self.szukajde.grid(column=0, row=2)
        self.szukajdb = Button(self.ramka1, text="SZUKAJ!", bg="slategray2", font=('Calibri Light', 15), command=self.wyniki2)
        self.szukajdb.grid(column=0, row=4)
        self.separator = Frame(self.newWindow1, height=3, width=300, bg="slategray4")
        self.separator.grid(column=0, row=5)
        self.szukajt = tk.Label(
            self.newWindow1, text="SZUKAJ PO TYTULE", font=('Calibri Light', 15))
        self.szukajt.grid(column=0, row=5)
        self.szukajte = tk.Entry(self.newWindow1, width=40)
        self.szukajte.grid(column=0, row=7)
        self.szukajtb = Button(
            self.newWindow1, text="SZUKAJ!", bg="slategray2", font=('Calibri Light', 15), command=self.wyniki)
        self.szukajtb.grid(column=0, row=9)

        self.newWindow1.grid_rowconfigure(3, minsize=10)
        self.newWindow1.grid_rowconfigure(5, minsize=30)
        self.newWindow1.grid_rowconfigure(8, minsize=30)
        self.newWindow1.grid_rowconfigure(10, minsize=30)
        self.szukajte.grid(column=0, row=6)
        #self.szukajtb = Button(
        #    self.newWindow1, text="Szukaj!", command=lambda: self.searchDatabase(self.szukajte.get()))
        self.szukajtb = Button(
            self.newWindow1, text="Szukaj!", command=self.wyniki)
        self.szukajtb.grid(column=0, row=7)
        # self.labelOdczyt = tk.Label(self.newWindow1, text=data, font=('Calibri Light', 15))
        # self.labelOdczyt.grid(column=0, row=3)

    def searchDatabase2(self, data):
        self.c.execute(
            '''SELECT * FROM notatki WHERE data = ? COLLATE NOCASE''', (data,))
        self.searchResult2 = self.c.fetchall()
        conn.commit()
        print(data)
        print(self.searchResult2)
        return self.searchResult2
       
    def wyniki2(self):
        self.newWindow4 = tk.Toplevel(self.master)
        lista2 = self.searchDatabase2(self.szukajde.get_date())
        for record in lista2:
            recordbutton = Button(self.newWindow4, text=record[1], bg="slategray2", font=('Calibri Light', 15))
            recordbutton.pack()

    def wyniki(self):
        self.newWindow2 = tk.Toplevel(self.master)
        self.resultLabel = tk.Label(self.newWindow2, text=(str(self.searchDatabase(self.szukajte.get()))))
        self.lista = self.searchDatabase(self.szukajte.get())
        for record in self.lista:
            recordbutton = Button(self.newWindow2, text=record[1] +"|" + record[0], bg="slategray2", font=('Calibri Light', 15), command=lambda: self.pokazNotatke(record[2]))

    def pokazNotke(self, Notka):
        self.newWindow3 = tk.Toplevel(self.master)
        self.notatkaLabel = Label(self.newWindow3, text=Notka[2])
        self.notatkaLabel.pack()

    def dodaj(self):
        self.notka = self.textfield.get("1.0", END)
        self.nazwanotki = self.tytul.get()

        print(self.notka)
        now = strftime("%d.%m.%Y")

        print(now)
        self.c.execute('''INSERT INTO notatki (data, nazwa, notatka) VALUES (?, ?, ?)''',
                       (now, self.nazwanotki, self.notka,))
        conn.commit()
        self.newWindow.destroy()
예제 #18
0
class Funçoes(Validadores):
    def conecta_bd(self):
        self.conn = sqlite3.connect("AGENDAMENTOS.db")
        self.cursor = self.conn.cursor()
        print("Conectando ao banco de dados")

    def desconecta_bd(self):
        self.conn.close()
        print("Desconectando ao banco de dados")

    def montaTabelas(self):
        self.conecta_bd()
        ### Criar tabela
        self.cursor.execute("""
            CREATE TABLE IF NOT EXISTS Agendas (
                COD INTEGER PRIMARY KEY,
                NOME_CLIENTE CHAR(40) NOT NULL,
                TELEFONE INTEGER(20),
                DATA date,
                HORA time              
            );
        """)
        self.conn.commit()
        print("Banco de dados criado")
        self.desconecta_bd()

    def Calendario(self):
        self.cal = Calendar(self.Main, fg='black', locale='pt_br')
        self.cal.place(relx=0.75, rely=0.08)
        self.btsalva = Button(self.Main,
                              text='Salvar',
                              command=self.Salvar,
                              bg='#00FF7F')
        self.btsalva.place(relx=0.75, rely=0.27, relwidth=0.15)
        self.bt_fechar = Button(self.Main,
                                text='Sair',
                                command=self.Fechar,
                                bg='red')
        self.bt_fechar.place(relx=0.90, rely=0.27, relwidth=0.05)

    def Fechar(self):
        self.cal.destroy()
        self.btsalva.destroy()
        self.bt_fechar.destroy()

    def Agendar(self):
        self.conecta_bd()
        self.montaTabelas()

        self.entry_cod = Entry(self.Main)
        self.entry_cod.place(relx=0.15, rely=0.05, relwidth=0.04)

        self.entrynome = Entry(self.Main)
        self.entrynome.place(relx=0.25, rely=0.10, relwidth=0.40)
        self.lbnome = Label(self.Main, text='Nome', background='white')
        self.lbnome.place(relx=0.15, rely=0.10)

        self.entrytele = Entry(self.Main,
                               validate='key',
                               validatecommand=self.vdTele)
        self.entrytele.place(relx=0.25, rely=0.20, relwidth=0.40)
        self.lbtele = Label(self.Main, text='Telefone', background='white')
        self.lbtele.place(relx=0.15, rely=0.20)

        self.entryhora = Entry(self.Main,
                               validate='key',
                               validatecommand=self.vdhora)
        self.entryhora.place(relx=0.25, rely=0.30, relwidth=0.05)
        self.lbhora = Label(self.Main, text='Hora', background='white')
        self.lbhora.place(relx=0.15, rely=0.30)

        self.entrydata = Entry(self.Main)
        self.entrydata.place(relx=0.40, rely=0.30, relwidth=0.10)
        self.lbdata = Label(self.Main, text='Data', background='white')
        self.lbdata.place(relx=0.35, rely=0.30)

        self.bt_calendario = Button(self.Main,
                                    text='Calendario',
                                    command=self.Calendario)
        self.bt_calendario.place(relx=0.55, rely=0.30)

        self.bt_altera = Button(self.Main,
                                text='Alterar',
                                command=self.Alteraagenda)
        self.bt_altera.place(relx=0.65, rely=0.30)

    def Salvar(self):
        dataini = self.cal.get_date()
        self.entrydata.delete(0, END)
        self.entrydata.insert(END, dataini)
        self.conecta_bd()
        self.conn.execute(
            '''
        insert into Agendas (NOME_CLIENTE,TELEFONE,DATA,HORA) values (?,?,?,?)''',
            (self.entrynome.get(), self.entrytele.get(), self.entrydata.get(),
             self.entryhora.get()))
        self.conn.commit()
        self.desconecta_bd()
        self.limpa_cliente()
        self.entrynome.destroy()
        self.lbnome.destroy()
        self.entryhora.destroy()
        self.lbhora.destroy()
        self.entrytele.destroy()
        self.lbtele.destroy()
        self.entrydata.destroy()
        self.lbdata.destroy()
        self.bt_calendario.destroy()
        self.btsalva.destroy()
        self.cal.destroy()
        self.entry_cod.destroy()
        self.bt_altera.destroy()
        self.bt_fechar.destroy()
        self.Tarefas()

    def OnDoubleClick(self, event):
        self.limpa_cliente()
        self.listaCli.selection()

        for n in self.listaCli.selection():
            col1, col2, col3, col4, col5 = self.listaCli.item(n, 'values')
            self.entry_cod.insert(END, col1)
            self.entrynome.insert(END, col2)
            self.entrytele.insert(END, col3)
            self.entrydata.insert(END, col4)
            self.entryhora.insert(END, col5)

    def Tarefas(self):
        self.listaCli.delete(*self.listaCli.get_children())
        self.conecta_bd()
        dia = self.data_e_hora = strftime('%d/%m/%Y')
        lista = self.conn.execute('''
       SELECT * FROM Agendas where data like ('%s')ORDER BY NOME_CLIENTE ASC'''
                                  % dia)
        for i in lista:
            self.listaCli.insert("", END, values=i)
        self.desconecta_bd()
        self.limpa_cliente()

    def VerMes(self):
        self.Agendar()
        self.listaCli.delete(*self.listaCli.get_children())
        self.conecta_bd()
        meses = self.data_e_hora = strftime('/%m/%Y')
        mes = ('%') + meses
        lista = self.conn.execute('''
        SELECT * FROM Agendas where data like ('%s')ORDER BY data ASC''' % mes)
        for i in lista:
            self.listaCli.insert("", END, values=i)
        self.desconecta_bd()

    def Notas(self):
        print('Atualizando')

    def Validaentrada(self):
        self.vdhora = (self.root.register(self.ValidaHora), "%P")
        self.vdTele = (self.root.register(self.ValidaTele), "%P")

    def Alteraagenda(self):

        self.conecta_bd()
        self.conn.execute(
            '''UPDATE Agendas set NOME_CLIENTE=?,TELEFONE=?,DATA=?,HORA=? where COD=?''',
            (self.entrynome.get(), self.entrytele.get(), self.entrydata.get(),
             self.entryhora.get(), self.entry_cod.get()))
        self.conn.commit()
        self.desconecta_bd()
        self.limpa_cliente()
        self.Tarefas()

    def limpa_cliente(self):
        self.entry_cod.delete(0, END)
        self.entrynome.delete(0, END)
        self.entrytele.delete(0, END)
        self.entrydata.delete(0, END)
        self.entryhora.delete(0, END)
예제 #19
0
class SchichtView(tk.Toplevel):
    def __init__(self, parent_view, asn_liste, adressliste):
        super().__init__(parent_view)

        # unterframes zur optisch-logischen Einteilung
        self.asn_frame = tk.Frame(self)
        self.datetime_frame = tk.Frame(self)
        self.template_frame = tk.Frame(self.asn_frame)
        self.add_options_frame = tk.Frame(self)
        self.add_options_checkbuttons_frame = tk.Frame(self.add_options_frame)
        self.save_buttons_frame = tk.Frame(self)

        self.asn_dropdown = Combobox(self.asn_frame,
                                     values=asn_liste,
                                     width=38,
                                     state="readonly")
        self.asn_dropdown.set(-1)
        self.selected_template = tk.IntVar()

        self.asn_stammdaten_form = AsnStammdatenView(
            parent_view=self.asn_frame)

        self.startdatum_input = Calendar(self.datetime_frame,
                                         date_pattern='MM/dd/yyyy')
        # day=day,
        # month=month,
        # year=year)
        self.startzeit_input = TimePicker(self.datetime_frame)
        self.endzeit_input = TimePicker(self.datetime_frame)
        self.startzeit_input.bind('<FocusOut>',
                                  self.nachtschicht_durch_uhrzeit)
        self.endzeit_input.bind('<FocusOut>', self.nachtschicht_durch_uhrzeit)

        self.enddatum_input = Calendar(self.datetime_frame,
                                       date_pattern='MM/dd/yyyy')
        # , day=day, month=month, year=year)

        self.abweichende_adresse_beginn = PostadresseView(
            self.add_options_frame)
        self.abweichende_adresse_ende = PostadresseView(self.add_options_frame)

        self.abweichende_adresse_beginn_dropdown = Combobox(
            self.add_options_frame,
            values=adressliste,
            width=38,
            state="readonly")
        self.abweichende_adresse_beginn_dropdown.set(-2)

        self.abweichende_adresse_ende_dropdown = Combobox(
            self.add_options_frame,
            values=adressliste,
            width=38,
            state="readonly")
        self.abweichende_adresse_ende_dropdown.set(-2)

        self.ist_at = tk.IntVar()
        self.ist_pcg = tk.IntVar()
        self.ist_rb = tk.IntVar()
        self.ist_afg = tk.IntVar()
        self.ist_at_button = tk.Checkbutton(
            self.add_options_checkbuttons_frame,
            text="AT",
            onvalue=1,
            offvalue=0,
            variable=self.ist_at)
        self.ist_pcg_button = tk.Checkbutton(
            self.add_options_checkbuttons_frame,
            text="PCG",
            onvalue=1,
            offvalue=0,
            variable=self.ist_pcg)
        self.ist_rb_button = tk.Checkbutton(
            self.add_options_checkbuttons_frame,
            text="Kurzfristig (RB/BSD)",
            onvalue=1,
            offvalue=0,
            variable=self.ist_rb)
        self.ist_afg_button = tk.Checkbutton(
            self.add_options_checkbuttons_frame,
            text="Ausfallgeld",
            onvalue=1,
            offvalue=0,
            variable=self.ist_afg)

        # formbuttons
        self.save_button = tk.Button(self.save_buttons_frame,
                                     text="Daten speichern")
        self.exit_button = tk.Button(self.save_buttons_frame, text="Abbrechen")
        # command=self.destroy)
        self.saveandnew_button = tk.Button(self.save_buttons_frame,
                                           text="Daten speichern und neu")
        # command=lambda: self.action_save_neue_schicht(undneu=1))

    def draw_templates(self, template_list):
        for child in self.template_frame.winfo_children():
            child.destroy()

        if not template_list:
            self.add_template_text()
        else:
            for template in template_list:
                text = template.bezeichner
                text += " von " + template.beginn.strftime('%H:%M') \
                        + " bis " + template.ende.strftime('%H:%M')
                button = tk.Radiobutton(
                    self.template_frame,
                    text=text,
                    variable=self.selected_template,
                    value=template.id,
                    command=lambda: self.change_template(template_list))
                button.pack()

    def nachtschicht_durch_uhrzeit(self, event=None):
        start = time(hour=int(self.startzeit_input.hourstr.get()),
                     minute=int(self.startzeit_input.minstr.get()))
        ende = time(hour=int(self.endzeit_input.hourstr.get()),
                    minute=int(self.endzeit_input.minstr.get()))

        beginn = self.startdatum_input.selection_get()

        if ende < start:
            enddatum = beginn + timedelta(days=1)
        else:
            enddatum = beginn

        self.enddatum_input.selection_set(enddatum)

    def change_template(self, template_list):
        template_id = self.selected_template.get()
        for template in template_list:
            if template_id == template.id:
                self.startzeit_input.hourstr.set(
                    template.beginn.strftime('%H'))
                self.startzeit_input.minstr.set(template.beginn.strftime('%M'))
                self.endzeit_input.hourstr.set(template.ende.strftime('%H'))
                self.endzeit_input.minstr.set(template.ende.strftime('%M'))
                self.nachtschicht_durch_uhrzeit()
                break

    def draw(self):

        # positionierung der Unterframes
        self.asn_frame.grid(row=0, column=0, sticky=tk.NW)
        self.datetime_frame.grid(row=0, column=1, sticky=tk.NW)
        self.template_frame.grid(row=1, column=0, sticky=tk.NW, columnspan=4)
        self.add_options_frame.grid(row=2,
                                    column=0,
                                    columnspan=2,
                                    sticky=tk.NW)
        self.add_options_checkbuttons_frame.grid(row=3,
                                                 column=0,
                                                 columnspan=2,
                                                 sticky=tk.NW)
        self.save_buttons_frame.grid(row=3,
                                     column=0,
                                     columnspan=2,
                                     sticky=tk.NE)

        # asn-frame
        asn_label = tk.Label(self.asn_frame, text='ASN auswählen')
        asn_label.grid(row=0, column=0, sticky=tk.NW)
        self.asn_dropdown.grid(row=0, column=1, sticky=tk.NE)
        self.asn_stammdaten_form.grid(row=1,
                                      column=0,
                                      columnspan=2,
                                      sticky=tk.NW)

        # datetime-frame
        startdatum_label = tk.Label(self.datetime_frame, text='Beginn')
        startdatum_label.grid(row=0, column=0, sticky=tk.NW)
        self.startdatum_input.grid(row=1, column=0, sticky=tk.NW, columnspan=2)
        self.startzeit_input.grid(row=0, column=1, sticky=tk.NW)

        enddatum_label = tk.Label(self.datetime_frame, text='Ende')
        enddatum_label.grid(row=0, column=2, sticky=tk.NW)
        self.enddatum_input.grid(row=1, column=2, sticky=tk.NW, columnspan=2)
        self.endzeit_input.grid(row=0, column=3, sticky=tk.NW)

        # add-options-frame
        abweichende_adresse_beginn_label = tk.Label(
            self.add_options_frame, text="Adresse zu beginn der Schicht?")
        abweichende_adresse_ende_label = tk.Label(
            self.add_options_frame, text="Adresse zum Ende der Schicht?")
        abweichende_adresse_beginn_label.grid(row=0, column=0, sticky=tk.NW)
        self.abweichende_adresse_beginn_dropdown.grid(row=1,
                                                      column=0,
                                                      sticky=tk.NE)
        self.abweichende_adresse_beginn.grid(row=2, column=0, sticky=tk.NW)
        abweichende_adresse_ende_label.grid(row=0, column=1, sticky=tk.NW)
        self.abweichende_adresse_ende_dropdown.grid(row=1,
                                                    column=1,
                                                    sticky=tk.NE)
        self.abweichende_adresse_ende.grid(row=2, column=1, sticky=tk.NW)

        self.ist_at_button.grid(row=0, column=0, sticky=tk.NW)
        self.ist_pcg_button.grid(row=0, column=1, sticky=tk.NW)
        self.ist_rb_button.grid(row=0, column=2, sticky=tk.NW)
        self.ist_afg_button.grid(row=0, column=3, sticky=tk.NW)

        # save-button-frame
        self.save_button.grid(row=0, column=0)
        self.exit_button.grid(row=0, column=1)
        self.saveandnew_button.grid(row=0, column=2)

    @staticmethod
    def hide(frame: tk.Frame):
        frame.grid_remove()

    @staticmethod
    def show(frame: tk.Frame):
        frame.grid()

    def add_template_text(self):
        # template-frame
        template_text = tk.Label(
            self.template_frame,
            justify="left",
            text='Wenn der Assistent "Schicht-Vorlagen" hat,\n'
            'stehen diese hier zur Auswahl.\n\n'
            'Das ist absolut anzuraten, da es das Eintragen\n'
            'von Schichten deutlich beschleunigt. \n\n'
            'Die Möglichkeit dazu findest Du im Hauptfenster unter: \n'
            'Bearbeiten -> ASN bearbeiten')
        template_text.pack()

    def set_data(self, **kwargs):
        """
        parst alle daten ins Formular

        :param kwargs:
        :return:
        """
        if 'asn' in kwargs.keys():
            self.asn_dropdown.set(kwargs['asn'])
        if 'asn_stammdaten' in kwargs.keys():
            self.asn_stammdaten_form.set_data(**kwargs['asn_stammdaten'])
        if 'beginn' in kwargs.keys():
            self.startdatum_input.selection_set(date=kwargs['beginn'])
            self.startzeit_input.hourstr.set(kwargs['beginn'].strftime('%H'))
            self.startzeit_input.minstr.set(kwargs['beginn'].strftime('%M'))
        if 'ende' in kwargs.keys():
            self.enddatum_input.selection_set(date=kwargs['ende'])
            self.endzeit_input.hourstr.set(kwargs['ende'].strftime('%H'))
            self.endzeit_input.minstr.set(kwargs['ende'].strftime('%M'))

        self.ist_at.set(
            1 if 'ist_at' in kwargs.keys() and kwargs['ist_at'] else 0)
        self.ist_pcg.set(
            1 if 'ist_pcg' in kwargs.keys() and kwargs['ist_pcg'] else 0)
        self.ist_rb.set(
            1 if 'ist_rb' in kwargs.keys() and kwargs['ist_rb'] else 0)
        self.ist_afg.set(
            1 if 'ist_afg' in kwargs.keys() and kwargs['ist_afg'] else 0)

        # TODO Zurücksetzen bei Change ASN
        if 'abweichende_adresse_beginn' in kwargs.keys():
            if kwargs['abweichende_adresse_beginn']:
                self.abweichende_adresse_beginn_dropdown.set(
                    kwargs['abweichende_adresse_beginn'])

        if 'abweichende_adresse_ende' in kwargs.keys():
            if kwargs['abweichende_adresse_ende']:
                self.abweichende_adresse_ende_dropdown.set(
                    kwargs['abweichende_adresse_ende'])

    def get_data(self):

        return {
            'asn_id':
            self.asn_dropdown.get(),
            'asn_stammdaten':
            self.asn_stammdaten_form.get_data(),
            'startdatum':
            self.startdatum_input.get_date(),
            'startzeit_stunde':
            self.startzeit_input.hourstr.get(),
            'startzeit_minute':
            self.startzeit_input.minstr.get(),
            'enddatum':
            self.enddatum_input.get_date(),
            'endzeit_stunde':
            self.endzeit_input.hourstr.get(),
            'endzeit_minute':
            self.endzeit_input.minstr.get(),
            'abweichende_adresse_beginn':
            self.abweichende_adresse_beginn_dropdown.get(),
            'abweichende_adresse_beginn_data':
            self.abweichende_adresse_beginn.get_data(),
            'abweichende_adresse_ende':
            self.abweichende_adresse_ende_dropdown.get(),
            'abweichende_adresse_ende_data':
            self.abweichende_adresse_ende.get_data(),
            'ist at':
            self.ist_at.get(),
            'ist pcg':
            self.ist_pcg.get(),
            'ist rb':
            self.ist_rb.get(),
            'ist afg':
            self.ist_afg.get()
        }
class AssistentNewEditView(tk.Toplevel):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        headline = tk.Label(self, text="Wer bist du denn eigentlich?")
        vorname_label = tk.Label(self, text="Vorname")
        self.vorname_input = tk.Entry(self, bd=5, width=40)
        name_label = tk.Label(self, text="Nachname")
        self.name_input = tk.Entry(self, bd=5, width=40)
        email_label = tk.Label(self, text="Email")
        self.email_input = tk.Entry(self, bd=5, width=40)
        strasse_label = tk.Label(self, text="Straße/Hausnummer")
        self.strasse_input = tk.Entry(self, bd=5, width=29)
        self.hausnummer_input = tk.Entry(self, bd=5, width=9)
        plz_label = tk.Label(self, text="Postleitzahl")
        self.plz_input = tk.Entry(self, bd=5, width=40)
        stadt_label = tk.Label(self, text="Stadt")
        self.stadt_input = tk.Entry(self, bd=5, width=40)
        einstellungsdatum_label = tk.Label(
            self, text="Seit wann bei ad? (tt.mm.JJJJ)")
        self.einstellungsdatum_input = Calendar(self)
        self.save_button = tk.Button(self, text="Daten speichern")
        self.exit_button = tk.Button(self,
                                     text="Abbrechen",
                                     command=self.destroy)

        # ins Fenster packen
        headline.grid(row=0, column=0, columnspan=3)
        vorname_label.grid(row=1, column=0)
        self.vorname_input.grid(row=1, column=1, columnspan=2)
        name_label.grid(row=2, column=0)
        self.name_input.grid(row=2, column=1, columnspan=2)
        email_label.grid(row=3, column=0)
        self.email_input.grid(row=3, column=1, columnspan=2)
        strasse_label.grid(row=4, column=0)
        self.strasse_input.grid(row=4, column=1)
        self.hausnummer_input.grid(row=4, column=2)
        plz_label.grid(row=5, column=0)
        self.plz_input.grid(row=5, column=1, columnspan=2)
        stadt_label.grid(row=6, column=0)
        self.stadt_input.grid(row=6, column=1, columnspan=2)
        einstellungsdatum_label.grid(row=7, column=0, sticky="nw")
        self.einstellungsdatum_input.grid(row=7, column=1)

        self.exit_button.grid(row=8, column=0)
        self.save_button.grid(row=8, column=1)

    def set_data(self, **kwargs):
        self.vorname_input.insert(0, kwargs['vorname'])
        self.name_input.insert(0, kwargs['name'])
        self.email_input.insert(0, kwargs['email'])
        self.strasse_input.insert(0, kwargs['strasse'])
        self.hausnummer_input.insert(0, kwargs['hausnummer'])
        self.plz_input.insert(0, kwargs['plz'])
        self.stadt_input.insert(0, kwargs['stadt'])
        self.einstellungsdatum_input.selection_set(kwargs['einstellungsdatum'])

    def get_data(self):
        einstellungsdatum_date_obj = datetime.strptime(
            self.einstellungsdatum_input.get_date(), '%m/%d/%y')

        return {
            'name': self.name_input.get(),
            'vorname': self.vorname_input.get(),
            'email': self.email_input.get(),
            'einstellungsdatum': einstellungsdatum_date_obj,
            'strasse': self.strasse_input.get(),
            'hausnummer': self.hausnummer_input.get(),
            'plz': self.plz_input.get(),
            'stadt': self.stadt_input.get()
        }
예제 #21
0
from tkinter import *
from tkcalendar import Calendar

# Create Object
root = Tk()

# Add Calender
cal = Calendar(root, selectmode='day', year=2021, month=5, day=19)

cal.pack(pady=20)


def grad_date():
    date.config(text="Selected Date is: " + cal.get_date())


print(cal.get_date())

# Add Button and Label
Button(root, text="Get Date", command=grad_date).pack(pady=20)

date = Label(root, text="")
date.pack(pady=20)

# Excecute Tkinter
root.mainloop()
def open():
    global cal, end_button, pick_button, prev_date, root, startCal, endCal, startDate, endDate, CLUSTERS, CLUSTERS_NAMES, CLUSTERS_DATES, loop, flagaRandom, random_button, randtxt, startDate, endDate
    if not startDate:
        startDate = startCal.get_date()
        endDate = endCal.get_date()
    switch = True
    if checkProperDate(startDate, endDate) == 0:
        return
    CLUSTERS, CLUSTERS_NAMES, CLUSTERS_DATES = createClusters(
        startDate.timetuple().tm_yday,
        endDate.timetuple().tm_yday)
    root.destroy()
    root = tkinter.Tk()
    root.configure(background="white")
    root.title('Date Picker')
    img = tkinter.Image("photo", file="data/calendar.gif")
    root.tk.call('wm', 'iconphoto', root._w, img)

    style = ttk.Style(root)
    style.theme_use('default')
    root.geometry("1000x800")
    my_label = tkinter.Label(root, text="Select a date")
    cal = Calendar(root,
                   selectmode="day",
                   year=2021,
                   disabledbackground="red",
                   headersbackground="slateblue",
                   normalbackground="white",
                   weekendbackground="mediumpurple",
                   selectbackground="salmon",
                   showothermonthdays=False)
    cal.config(background="black")
    cal.pack(pady=20, fill="both", expand=True)
    prev_date = cal.get_date()

    def grab_date():
        global picked_ids
        picked_date = cal.get_date()
        # my_label.config(text="Picked Date " + picked_date)
        if picked_date == "":
            messagebox.showerror("Error", "First select a date!")
            return
        if datetime.strptime(picked_date,
                             "%m/%d/%y") not in picked_ids["dates"]:
            picked_ids["ids"].append(
                cal.calevent_create(datetime.strptime(picked_date, "%m/%d/%y"),
                                    "Not provided", 'message'))
            picked_ids["dates"].append(
                datetime.strptime(picked_date, "%m/%d/%y"))
            date_index = datetime.strptime(picked_date,
                                           "%m/%d/%y").timetuple().tm_yday
            picked_ids["indexes"].append(date_index)
        else:
            idx = picked_ids["dates"].index(
                datetime.strptime(picked_date, "%m/%d/%y"))
            id = picked_ids["ids"][idx]
            date = cal.calevents[id]['date']
            del cal.calevents[id]
            del cal._calevent_dates[date]
            cal._reset_day(date)
            picked_ids["ids"].pop(idx)
            picked_ids["dates"].pop(idx)
            picked_ids["indexes"].pop(idx)
            my_label.config(text="Selected date: None")
            global prev_date
            prev_date = None
            cal._sel_date = None

    def random_events_button():
        global picked_ids, endDate, startDate, cal, root, flagaRandom, randtxt, random_button
        if flagaRandom:
            ilosc = endDate.timetuple().tm_yday - startDate.timetuple(
            ).tm_yday + 1
            daty = np.unique(
                np.random.randint(startDate.timetuple().tm_yday,
                                  endDate.timetuple().tm_yday + 1,
                                  np.random.randint(1, ilosc + 1)))
            for data in daty:
                datatemp = (datetime(2021, 1, 1) + timedelta(int(data) - 1))
                if datatemp not in picked_ids["dates"]:
                    picked_ids["ids"].append(
                        cal.calevent_create(datatemp.date(), "Not provided",
                                            "message"))
                    picked_ids["dates"].append(datatemp)
                    picked_ids["indexes"].append(data)
            flagaRandom = False
            randtxt = "Remove all"
            # cal._display_calendar()
        else:
            flagaRandom = True
            randtxt = "Select random dates"
            cal.calevent_remove("all")
            picked_ids["ids"] = []
            picked_ids["dates"] = []
            picked_ids["indexes"] = []
        if pick_button.winfo_exists():
            random_button["text"] = randtxt

    def date_check():
        global prev_date, butText, pick_button, pick_button, startDate, endDate, after2
        if prev_date != cal.get_date():
            if cal.get_date() == "":
                my_label.config(text="Select a date")
            else:
                my_label.config(text="Selected date: " + cal.get_date())
            prev_date = cal.get_date()
        if cal.get_date() == "":
            butText = "Pick Date"
        elif datetime.strptime(cal.get_date(),
                               "%m/%d/%y") in picked_ids["dates"]:
            butText = "Unpick Date"
        else:
            butText = "Pick Date"
        if pick_button.winfo_exists():
            pick_button["text"] = butText
        if cal.get_date() != "":
            calendar_date = datetime.strptime(cal.get_date(),
                                              "%m/%d/%y").date()
            if calendar_date > endDate:
                messagebox.showerror(
                    "Error",
                    f"Selected date must be from {startDate.strftime('%d/%m/%Y')} to {endDate.strftime('%d/%m/%Y')}"
                )
                cal.selection_set(endDate)
            elif calendar_date < startDate:
                messagebox.showerror(
                    "Error",
                    f"Selected date must be from {startDate.strftime('%d/%m/%Y')} to {endDate.strftime('%d/%m/%Y')}"
                )
                cal.selection_set(startDate)
        after2 = root.after(100, date_check)

    def stop_selecting():
        global cal, end_button
        cal._remove_selection()
        cal.__setitem__("selectmode", "none")
        pick_button.destroy()
        random_button.destroy()
        end_button["text"] = "Show results"
        end_button["command"] = results
        dates = []
        for date in picked_ids["dates"]:
            dates.append(datetime.strftime(date, '%d/%m/%y'))
        dates = str(dates).replace('\'', '').replace(', ', ', ').replace(
            '[', '').replace(']', '')
        my_label.config(text=f"Selected dates: {dates}",
                        wraplength=1000,
                        justify="center")

    def results():
        global picked_ids, startDate, endDate, root, switch, img, loop, after2, CLUSTERS, CLUSTERS_NAMES, CLUSTERS_DATES, PRZEROBIONY, Top, restart_button
        # ustawienia okna
        switch = False
        root.after_cancel(loop)
        root.after_cancel(after2)
        Top = tkinter.Toplevel(root, )
        Top.configure(background="white")
        Top.title('Result')
        Top.grab_set()
        img = tkinter.Image("photo", file="data/calendar.gif")
        # root.tk.call('wm', 'iconphoto', root._w, img)
        style = ttk.Style(Top)
        style.theme_use('default')
        # # wyliczamy długość tablicy
        PERIODICITY = np.zeros(
            (endDate.timetuple().tm_yday - startDate.timetuple().tm_yday + 1),
            int)
        for i in range(PERIODICITY.shape[0]):
            PERIODICITY[i] = 0 if i + startDate.timetuple(
            ).tm_yday in picked_ids["indexes"] else i + startDate.timetuple(
            ).tm_yday  # UNIVERSE
        PERIODICITY = PERIODICITY[PERIODICITY[:] != 0]
        PRZEROBIONY = np.multiply(CLUSTERS, CLUSTERS_DATES).tolist()
        NPRZEROBIONY = []
        NNAZWY = []
        for i in range(len(PRZEROBIONY)):
            NNAZWY.append(CLUSTERS_NAMES[i])
            NPRZEROBIONY.append(set(filter((0).__ne__, PRZEROBIONY[i])))
        print("OKRES: ", PERIODICITY)
        # print("prze",NPRZEROBIONY)
        wyniki = problem(
            set(PERIODICITY.copy()),
            NPRZEROBIONY.copy(),
        )
        msg = ""
        przerywnik = "," if len(wyniki) > 2 else "plus"
        exception = ""
        exceptionplus = ""
        res = set([])
        for wynik in wyniki:
            idx = NPRZEROBIONY.index(wynik)
            # print(idx)
            if msg == "" and NNAZWY[idx][0] != "f":
                msg += "'" + NNAZWY[idx] + "'"
            elif msg == "" and NNAZWY[idx][0] == "f":
                msg += NNAZWY[idx][:5] + "'" + NNAZWY[idx][5:] + "'"
            elif NNAZWY[idx][0] == "f":
                msg += przerywnik + " " + NNAZWY[idx][:5] + "'" + NNAZWY[idx][
                    5:] + "'"
            else:
                msg += f" {przerywnik} '{NNAZWY[idx]}'"
            res = res | wynik
        if len(res - set(PERIODICITY)) > 0 or len(set(PERIODICITY) - res) > 0:
            diffs = []
            diffsplus = []
            if len(res - set(PERIODICITY)) > 0:
                diffs = sorted(res - set(PERIODICITY))
                difftxt = "with the exception of "
            if len(set(PERIODICITY) - res) > 0:
                # print("X")
                diffsplus = sorted(set(PERIODICITY) - res)
                diffplus = "plus on "
            for diff in diffs:
                datetemp = (datetime(2021, 1, 1) +
                            timedelta(int(diff) - 1)).strftime('%d/%m/%Y')
                exception += f"{datetemp}" if exception == "" else f", {datetemp}"
            for diff in diffsplus:
                datetemp = (datetime(2021, 1, 1) +
                            timedelta(int(diff) - 1)).strftime('%d/%m/%Y')
                exceptionplus += f"{datetemp}" if exceptionplus == "" else f", {datetemp}"
        if PERIODICITY.shape[0] != 0:
            exceptionplus = diffplus + exceptionplus if exceptionplus != "" else ""
            exception = difftxt + exception if exception != "" else ""
            preposition = "on" if msg[0] != 'f' else ""
            lbl = tkinter.Label(
                Top,
                text=
                f"The service is provided {preposition} {msg} from {startDate.strftime('%d/%m/%Y')} to {endDate.strftime('%d/%m/%Y')} {exceptionplus} {exception}",
                wraplength=300,
                justify="center").pack(padx=10, pady=10)
        else:
            lbl = tkinter.Label(
                Top,
                text=
                f"The service is not provided from {startDate.strftime('%d/%m/%Y')} to {endDate.strftime('%d/%m/%Y')}",
                wraplength=300,
                justify="center").pack(padx=10, pady=10)

        def restart():
            global Top, open, butText, randtxt, indexes, picked_ids, flagaRandom

            def clear():

                # for windows
                if os.name == 'nt':
                    _ = os.system('cls')

                    # for mac and linux(here, os.name is 'posix')
                else:
                    _ = os.system('clear')

            clear()
            flagaRandom = True
            butText = "Pick Date"
            randtxt = "Select random dates"
            indexes = []
            picked_ids = {
                "ids": [],
                "dates": [],
                "indexes": [],
            }
            Top.destroy()
            open()

        restart_button = tkinter.Button(Top,
                                        text="Restart program",
                                        command=restart).pack(padx=10, pady=10)

    pick_button = tkinter.Button(root, text=butText, command=grab_date)
    random_button = tkinter.Button(root,
                                   text=randtxt,
                                   command=random_events_button)
    end_button = tkinter.Button(root, text="Finish", command=stop_selecting)
    if switch:
        loop = root.after(100, date_check)
    else:
        print("[ERROR]")
        root.after_cancel(loop)
        loop = None
    my_label.pack(pady=10)
    pick_button.pack(pady=10)
    random_button.pack(pady=10)
    end_button.pack(padx=100)
예제 #23
0
class App:
    ''' Interfaz básica del módulo tkinter y se agrega el widget tkcalendar.Calendar
        Más info en https://pypi.org/project/tkcalendar/
    '''

    def __init__(self):
        # Interfaz base de tkinter.
        # Más información en https://docs.python.org/3/library/tkinter.html
        self.root = tk.Tk()

        # método que se ejecuta al cerrar la ventana
        self.root.protocol("WM_DELETE_WINDOW", self.exit)

        self.root.withdraw()
        self.root.title('Calendario Personal')

        # Widget para mostrar calendario
        self.top = tk.Toplevel(self.root)
        self.top.protocol("WM_DELETE_WINDOW", self.exit)

        # es necesario instalar el módulo tkcalendar
        # python -m pip install tkcalendar
        # más info en https://pypi.org/project/tkcalendar/
        self.cal = Calendar(self.top,
                            font="Arial 10", background='darkblue',
                            foreground='white', selectmode='day')

        self.cal.grid()

        # Boton para ver registros del día
        ttk.Button(
            self.top, text="Ver eventos",

            # Como command recibe el nombre de un método, no nos permite pasar argumentos.
            # Para ello, utilizamos lambda, que crea una función anónima.
            # Puede recibir varios parámetros pero puede ejecutar una sola expresión/acción.
            # Más documentación en https://docs.python.org/3/reference/expressions.html#lambda
            command=lambda: ListView(
                root=self.root,
                day=self.cal.get_date()
            )).grid(sticky="ew", pady=5, padx=5)

        # Botón para crear un nuevo evento
        ttk.Button(
            self.top, text="Nuevo evento",
            command=lambda: EventoForm(
                self.root,
            )).grid(sticky="ew", pady=5, padx=5)

        # Loop para mostrar la ventana sin cerrarse
        self.root.mainloop()

    def exit(self):
        """ Cierr conexión a base de datos y todas las interfaces gráficas """

        # Cierra conexión a la base de datos
        ce.close_conn(ce.DB_CONN)

        # Cierra ventana de Calendario (widget)
        self.top.quit()
        self.top.destroy()

        # Cierra ventana principal
        self.root.quit()
        self.root.destroy()

        # Cierra el intérprete de Python
        sys.exit()
예제 #24
0
class DateFrame(Frame):
    """
     DateFrame class creates:
    | ◉ Today     ○ Pick Date  |      # Pick Date displays a calendar
    |    Date: 04/06/2021      |
    """
    def __init__(self, root):
        self.root = root
        super().__init__(self.root, bg=BACKGROUND_COLOR)
        self.date_pattern = DATE_PATTERN
        self.date_to_pixela = pixela_today  # '20210406'
        self.calendar = Calendar(self,
                                 font='Arial 8',
                                 background='#000080',
                                 showweeknumbers=False,
                                 weekendforeground='#000000',
                                 weekendbackground='#ffffff',
                                 date_pattern=self.date_pattern,
                                 othermonthwebackground='#ffffff',
                                 othermonthbackground='#ffffff')
        # ◉Today
        self.today = Radiobutton(self,
                                 command=self.set_today,
                                 text="Today ",
                                 value=0,
                                 variable=radio_state,
                                 bg=BACKGROUND_COLOR)
        self.today.grid(row=0, column=0, sticky='w')

        # ◉Pick Date
        self.pick_date = Radiobutton(self,
                                     command=self.show_calendar,
                                     text="Pick Date",
                                     value=1,
                                     variable=radio_state,
                                     bg=BACKGROUND_COLOR)
        self.pick_date.grid(row=0, column=1, sticky='w')

        # Date:  {04/06/2021}
        Label(self, text="Date: ", bg=BACKGROUND_COLOR, padx=10).grid(row=1,
                                                                      column=0)
        self.main_date = Label(self,
                               text="",
                               bg=BACKGROUND_COLOR,
                               font=('Arial', 12, 'bold'))
        self.main_date.grid(row=1, column=1, sticky='w')

        self.set_today()  # output today's date right away

    def change_date_pattern(self, option):  # to be used by Options in MainMenu
        self.date_pattern = option
        self.calendar = Calendar(self,
                                 font='Arial 8',
                                 background='#000080',
                                 showweeknumbers=False,
                                 weekendforeground='#000000',
                                 weekendbackground='#ffffff',
                                 date_pattern=option,
                                 othermonthwebackground='#ffffff',
                                 othermonthbackground='#ffffff')

        keep_format = messagebox.askyesno(
            title="Keep Format",
            message="Do you wish to keep this date format \n"
            "for the next times you open this program?")
        if keep_format:
            with shelve.open(filename="user_options") as sf:
                sf["date_pattern"] = option

        self.set_today()

    def display(self, date):
        self.calendar.grid_forget()
        self.main_date.config(text=date)

    def set_today(self):
        self.date_to_pixela = pixela_today  # set back TODAY for pixe.la and display it
        if self.date_pattern == 'mm/dd/yyyy':
            self.display(today.strftime("%m/%d/%Y"))
        elif self.date_pattern == 'dd/mm/yyyy':
            self.display(today.strftime("%d/%m/%Y"))
        else:
            self.display(today.strftime("%Y/%m/%d"))

    def show_calendar(
            self
    ):  # displays new date label, at every click, and hides calendar
        self.calendar.grid(row=2, column=0, columnspan=2, sticky='w')

        def format_day_from_calendar(event):  # won't work without "event" (?)
            date = self.get_pixela_date_from_calendar()
            self.display(date)

        self.calendar.bind("<<CalendarSelected>>", format_day_from_calendar)

    def get_pixela_date_from_calendar(self):
        get_date = self.calendar.get_date(
        )  # format retrieved depends on self.date_pattern
        date = get_date.split('/')
        if self.date_pattern == 'mm/dd/yyyy':
            self.date_to_pixela = ''.join([date[2], date[0], date[1]])
        elif self.date_pattern == 'dd/mm/yyyy':
            self.date_to_pixela = ''.join([date[2], date[1], date[0]])
        else:  # asian
            self.date_to_pixela = ''.join(date)
        return get_date
예제 #25
0
class ChangeStatement:
    """ Изменить состояние канала """
    def __init__(self, tree, iid, num, all_trees, logit):
        self.tree = tree
        self.iid = iid
        self.num = num
        self.all_trees = all_trees
        self.logit = logit
        self.row = self.tree.item(iid)
        self.key_tree = self.row['values'][0]
        self.all_values = all_values
        self.name = self.all_values[self.num][0][self.key_tree]
        self.add_in_table = all_values[self.num][1]

    def on_time(self):
        """ Выбрать время """

        self.top = tk.Toplevel()
        self.top.wm_title(self.name)
        lab1 = tk.Label(self.top,
                        text='Дата и время начала работ',
                        font=tkFont.Font(family=main_font, size=size_font))
        lab1.grid(row=0, column=0, columnspan=4, ipady=10, padx=10)
        self.cal1 = Calendar(self.top,
                             font="Arial 14",
                             selectmode="day",
                             year=datetime.datetime.today().year,
                             month=datetime.datetime.today().month,
                             day=datetime.datetime.today().day)
        self.cal1.grid(row=1, column=0, columnspan=4, rowspan=4, padx=10)
        self.time1 = AppTime(self.top)
        self.time1.grid(row=5, column=0, columnspan=4, pady=10)
        lab2 = tk.Label(self.top,
                        text='Дата и время завершения работ',
                        font=tkFont.Font(family=main_font, size=size_font))
        lab2.grid(row=0, column=5, columnspan=4, ipady=10)
        self.cal2 = Calendar(self.top,
                             font="Arial 14",
                             selectmode="day",
                             year=datetime.datetime.today().year,
                             month=datetime.datetime.today().month,
                             day=datetime.datetime.today().day)
        self.cal2.grid(row=1, column=5, columnspan=4, rowspan=4, padx=10)
        self.time2 = AppTime(self.top)
        self.time2.grid(row=5, column=5, columnspan=4, pady=10)

        self.day1 = self.cal1.get_date()
        self.day2 = self.cal2.get_date()
        self.hour1 = self.time1.hourstr.get()
        self.hour2 = self.time2.hourstr.get()
        self.min1 = self.time1.minstr.get()
        self.min2 = self.time2.minstr.get()
        text4 = tk.Label(self.top,
                         text='Добавьте комментарий:',
                         font=tkFont.Font(family=main_font, size=size_font))
        text4.grid(row=6, column=0, columnspan=5, padx=10)
        self.comment_text = ScrolledText.ScrolledText(self.top,
                                                      height=4,
                                                      width=40,
                                                      font=tkFont.Font(
                                                          family=main_font,
                                                          size=size_font),
                                                      wrap=WORD)
        self.comment_text.grid(row=7, column=0, columnspan=5, padx=10, pady=10)
        but1 = tk.Button(self.top,
                         text="Выбрать",
                         command=self.select_on_time,
                         activebackground='PaleGreen1',
                         font=tkFont.Font(family=main_font, size=size_font),
                         height=2,
                         width=10)
        but1.grid(row=7, column=6)
        but2 = tk.Button(self.top,
                         text="Отмена",
                         command=self.top.destroy,
                         activebackground='salmon',
                         font=tkFont.Font(family=main_font, size=size_font),
                         height=2,
                         width=10)
        but2.grid(row=7, column=7)
        self.top.resizable(height=False, width=False)

    def select_on_time(self):
        """ Отправить по времени"""

        date_order = [2, 0, 1]
        date_list1 = self.day1.split('/')
        date_list2 = self.day2.split('/')
        date_list1 = ['0' + i if len(i) == 1 else i for i in date_list1]
        date_list2 = ['0' + i if len(i) == 1 else i for i in date_list2]
        date_list1 = [date_list1[i] for i in date_order]
        date_list2 = [date_list2[i] for i in date_order]
        date_list1[0] = '20' + date_list1[0]
        date_list2[0] = '20' + date_list2[0]
        date1 = '-'.join(date_list1)
        date2 = '-'.join(date_list2)
        begin = date1 + ' ' + str(self.hour1) + ':' + str(self.min1)
        end = date2 + ' ' + str(self.hour2) + ':' + str(self.min2)
        new_value = {
            self.key_tree:
            [self.name, begin.encode('utf-8'),
             end.encode('utf-8')]
        }
        par1 = "Ремонт с".decode('koi8-r').encode('koi8-r')
        par2 = "до".decode('koi8-r').encode('koi8-r')
        for item in self.all_values.keys():
            for all_dict in self.all_values[item][0]:
                if self.name == self.all_values[item][0][all_dict]:
                    if item in list_moxa:
                        tree = self.all_trees[item]
                        remont = load_file('remont', item)
                        remont.update(new_value)
                        dump_file('remont', item, remont)
                        tree_num = self.key_tree - 1
                        row = tree.tree.get_children()[tree_num]
                        tree.tree.item(
                            row,
                            values=(str(self.key_tree),
                                    str(new_value[self.key_tree][0]),
                                    "%s %s %s %s" %
                                    (par1, new_value[self.key_tree][1], par2,
                                     new_value[self.key_tree][2])),
                            tags=("blue", ))
                        self.logit.warning(
                            'Канал %s в MOXA%s  отправлен на ремонт на период с %s до %s'
                            % (new_value[self.key_tree][0], self.num,
                               begin.encode('utf-8'), end.encode('utf-8')))
                        lst = [
                            self.key_tree,
                            str(new_value[self.key_tree][0]),
                            "%s %s %s %s" %
                            (par1, new_value[self.key_tree][1], par2,
                             new_value[self.key_tree][2]), "blue"
                        ]
                        new_value_add = {self.key_tree: lst}
                        self.add_in_table.update(new_value_add)
                        add_comment(self.comment_text.get('1.0', END), item,
                                    self.key_tree, self.name)
        self.top.destroy()

    def on_agreement(self):
        """ Отправить в ремонт до распоряжения"""

        date_today = datetime.datetime.now()
        begin = date_today.strftime("%Y-%m-%d %H:%M")
        end = 'распоряжения'.decode('koi8-r').encode('koi8-r')
        new_value = {self.key_tree: [self.name, begin.encode('utf-8'), end]}
        par1 = "Ремонт с".decode('koi8-r').encode('koi8-r')
        par2 = "до".decode('koi8-r').encode('koi8-r')
        for item in self.all_values.keys():
            for all_dict in self.all_values[item][0]:
                if self.name == self.all_values[item][0][
                        all_dict] and item in list_moxa:
                    tree = self.all_trees[item]
                    remont = load_file('remont', item)
                    remont.update(new_value)
                    dump_file('remont', item, remont)
                    tree_num = self.key_tree - 1
                    row = tree.tree.get_children()[tree_num]
                    tree.tree.item(
                        row,
                        values=(str(self.key_tree),
                                str(new_value[self.key_tree][0]),
                                "%s %s %s %s" %
                                (par1, new_value[self.key_tree][1], par2,
                                 new_value[self.key_tree][2])),
                        tags=("blue", ))
                    self.logit.warning(
                        'Канал %s в MOXA%s  отправлен на ремонт на период с %s до %s'
                        % (new_value[self.key_tree][0], item, begin, end))
                    lst = [
                        self.key_tree,
                        str(new_value[self.key_tree][0]),
                        "%s %s %s %s" % (par1, new_value[self.key_tree][1],
                                         par2, new_value[self.key_tree][2]),
                        "blue"
                    ]
                    new_value_add = {self.key_tree: lst}
                    self.add_in_table.update(new_value_add)

    def return_channel(self):
        """ Вернуть канал в работу"""

        for item in self.all_values.keys():
            for all_dict in self.all_values[item][0]:
                if self.name == self.all_values[item][0][all_dict]:
                    if item in list_moxa:
                        tree = self.all_trees[item]
                        remont = load_file('remont', item)
                        for key in remont.keys():
                            if key == self.key_tree:
                                del (remont[key])
                                dump_file('remont', item, remont)
                                tree_num = self.key_tree - 1
                                row = tree.tree.get_children()[tree_num]
                                moxa = self.all_values[item][0]
                                tree.tree.item(
                                    row,
                                    values=(str(self.key_tree),
                                            str(moxa[self.key_tree]),
                                            str('updating status...')),
                                    tags=("green", ))
                                self.logit.warning(
                                    'Канал %s в MOXA%s возвращен в работу' %
                                    (moxa[self.key_tree], item))
                                lst = [
                                    self.key_tree,
                                    str(moxa[self.key_tree]),
                                    'updating status...', "green"
                                ]
                                new_value_add = {self.key_tree: lst}
                                self.add_in_table.update(new_value_add)
class HomingWindow():
    def __init__(self, master, conn, main_win):
        # Init variable setup
        self.master = master
        self.conn = conn
        self.main_win = main_win
        self.animal_dict = {}  # Dictionary of row IDs and animal ID's
        #                             for adding animals to the list.

        # Window setup
        self.master.wm_title("Homing")
        CenterWindow(self.master)

        # Build the window
        self._build_frames()
        self._build_widgets()

    def _build_frames(self):
        # Right frame
        right_frame = ttk.Frame(self.master, width="250")
        right_frame.pack_propagate(0)
        right_frame.pack(side="right", fill="y")

        # - Calendar frame
        self.cal_frame = ttk.Frame(right_frame)
        self.cal_frame.pack(side="top")

        # - Add button frame
        self.add_frame = ttk.Frame(right_frame)
        self.add_frame.pack(side="top", fill="x")

        # - In-Rescue checkbox frame
        self.in_rescue_frame = ttk.Frame(right_frame)
        self.in_rescue_frame.pack(side="top", fill="x", anchor="w")

        # - Animal tree frame
        self.animal_tree_frame = ttk.Frame(right_frame)
        self.animal_tree_frame.pack(side="top", fill="both", expand=True)

        # - Add/Cancel buttons frame
        self.buttons_frame = ttk.Frame(right_frame)
        self.buttons_frame.pack(side="top", fill="x", anchor="s")

        # Main frame
        main_frame = ttk.Frame(self.master)
        main_frame.pack(side="left", fill="both", expand=True)

        # - Header frame
        self.header_frame = ttk.Frame(main_frame)
        self.header_frame.pack(side="top", fill="x")

        # - Data frame
        data_frame = ttk.Frame(main_frame)
        data_frame.pack(side="top", fill="both", expand=True)

        # -- Setting column list for inputs
        self.data_col = []
        # -- Column setup
        self.col_padd = 5
        self.col_paddl = self.col_padd + 1
        num_of_cols = 1  # Increase to add columns.
        for col in range(num_of_cols):
            self.data_col.insert(col, [0, 1])
            self.data_col[col][0] = ttk.Frame(data_frame)
            self.data_col[col][0].pack(side="left",
                                       fill="y",
                                       ipadx=5,
                                       anchor="n")
            self.data_col[col][1] = ttk.Frame(data_frame)
            self.data_col[col][1].pack(side="left",
                                       fill="y",
                                       ipadx=5,
                                       anchor="n")

        # -- Notes column
        note_frame = ttk.Frame(data_frame)
        note_frame.pack(side="left", fill="both", expand=True, padx=2)

        # --- Notes header frame
        self.note_header_frame = ttk.Frame(note_frame)
        self.note_header_frame.pack(side="top", fill="x")

        # --- Notes frame
        self.notes_frame = ttk.Frame(note_frame)
        self.notes_frame.pack(side="top", fill="both", anchor="n", expand=True)
        self.notes_frame.pack_propagate(0)

        # -- Animals column
        self.animal_frame = ttk.Frame(data_frame, width="200")
        self.animal_frame.pack(side="left", fill="both")
        self.animal_frame.pack_propagate(0)

    def _build_widgets(self):
        # =============
        # Right frame
        # =============
        # Calendar
        self.calendar = Calendar(self.cal_frame)
        self.calendar.pack(side="top", anchor="n")

        # Add button
        self.add_button = ttk.Button(self.add_frame,
                                     text="Add Animal",
                                     command=self._add_animal)
        self.add_button.pack(side="top", anchor="n", fill="x")

        # In-Rescue checkbox
        self.in_rescue_var = tk.IntVar()
        self.in_rescue = ttk.Checkbutton(self.in_rescue_frame,
                                         text="Only show animals in rescue: ",
                                         variable=self.in_rescue_var,
                                         command=self.refresh_animal_data)
        self.in_rescue.pack(side="left", anchor="w")
        self.in_rescue_var.set(1)

        # Build animal tree.
        animal_query = "SELECT * FROM Animal_ID_View"
        if self.in_rescue_var.get() == 1:
            animal_query += "_Active"
        md = BasicDbQuery(self.conn, animal_query)
        self.animal_tree = TreeBuild(self.animal_tree_frame,
                                     search=True,
                                     data=md[1],
                                     widths=[35, 300],
                                     headings=md[0])
        self.animal_tree.tree.bind("<Double-1>", lambda c: self._add_animal())

        # cancel / submit button
        self.submit = ttk.Button(self.buttons_frame,
                                 text="Submit",
                                 command=self._submit_entries)
        self.submit.pack(side="left", fill="x")
        self.cancel = ttk.Button(self.buttons_frame,
                                 text="Cancel",
                                 command=self.close_window)
        self.cancel.pack(side="right", fill="x")

        # =============
        # Header frame
        # =============
        # Title
        heading = ttk.Label(self.header_frame,
                            text="Collections / Adoptions",
                            font=self.main_win.font_title)
        heading.pack(side="left", anchor="nw", padx=10, pady=10)

        # =============
        # Column 0/1 Contents frame
        # =============

        # Homing or adoption radio button
        type_label = ttk.Label(self.data_col[0][0], text="Collection/Homing")
        type_label.pack(side="top", fill="x", pady=self.col_paddl)
        spacer = ttk.Label(self.data_col[0][0], text="")
        spacer.pack(side="top", fill="x", pady=self.col_paddl)
        self.home_type = tk.StringVar()
        self.radio_home = ttk.Radiobutton(self.data_col[0][1],
                                          value="home",
                                          text="Home to new owner",
                                          variable=self.home_type)
        self.radio_home.pack(side="top", fill="x", pady=self.col_padd)
        self.radio_home.invoke()
        self.radio_collect = ttk.Radiobutton(self.data_col[0][1],
                                             value="collect",
                                             text="Taking into the rescue",
                                             variable=self.home_type)
        self.radio_collect.pack(side="top", fill="x", pady=self.col_padd)

        # Name
        name_l = ttk.Label(self.data_col[0][0], text="Name")
        name_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.name_e = ttk.Entry(self.data_col[0][1])
        self.name_e.pack(side="top", fill="x", pady=self.col_padd)

        # Address 1
        address1_l = ttk.Label(self.data_col[0][0], text="Address line 1")
        address1_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.address1_e = ttk.Entry(self.data_col[0][1])
        self.address1_e.pack(side="top", fill="x", pady=self.col_padd)

        # Address 2
        address2_l = ttk.Label(self.data_col[0][0], text="Address line 2")
        address2_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.address2_e = ttk.Entry(self.data_col[0][1])
        self.address2_e.pack(side="top", fill="x", pady=self.col_padd)

        # Town
        town_l = ttk.Label(self.data_col[0][0], text="Town")
        town_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.town_e = ttk.Entry(self.data_col[0][1])
        self.town_e.pack(side="top", fill="x", pady=self.col_padd)

        # County
        county_l = ttk.Label(self.data_col[0][0], text="County")
        county_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.county_e = ttk.Entry(self.data_col[0][1])
        self.county_e.pack(side="top", fill="x", pady=self.col_padd)

        # Postcode
        postcode_l = ttk.Label(self.data_col[0][0], text="Postcode")
        postcode_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.postcode_e = ttk.Entry(self.data_col[0][1])
        self.postcode_e.pack(side="top", fill="x", pady=self.col_padd)

        # Phone number
        phone_num_l = ttk.Label(self.data_col[0][0], text="Phone Number")
        phone_num_l.pack(side="top", fill="x", ipady=self.col_paddl)
        self.phone_num_e = ttk.Entry(self.data_col[0][1])
        self.phone_num_e.pack(side="top", fill="x", pady=self.col_padd)

        # =============
        # notes frame frame
        # =============
        # - Notes items.
        # - Notes label
        self.notes_l = ttk.Label(self.note_header_frame,
                                 text="Notes:",
                                 anchor="n")
        self.notes_l.pack(side="top", fill="x")

        # - Notes text box
        text_scroll = tk.Scrollbar(self.notes_frame)
        self.text_box = tk.Text(self.notes_frame)
        text_scroll.pack(side="right", fill="y")
        self.text_box.pack(side="right", fill="y")
        text_scroll.config(command=self.text_box.yview)
        self.text_box.config(yscrollcommand=text_scroll.set)

        # =============
        # Animal frame
        # =============
        self.animal_l = ttk.Label(self.animal_frame,
                                  text="Animals to process:",
                                  anchor="n")
        self.animal_l.pack(side="top", fill="x")

    def _submit_entries(self):
        if len(self.animal_dict.values()) == 0:
            return
        # =============
        # Build the SQL Query for inserting the homing event.
        # =============
        query = """
                INSERT INTO Homing_Data (
                    Date,
                    Description,
                    Delivered_Or_Collected,
                    Name,
                    Address_1,
                    Address_2,
                    Town,
                    County,
                    Postcode,
                    Phone_Number)

                VALUES(
                    :date,
                    :description,
                    :delivered,
                    :name,
                    :addr1,
                    :addr2,
                    :town,
                    :county,
                    :postcode,
                    :phonenum)
                    """

        # Build the dictionary to fill the query
        sql_dict = {}

        # date
        date = self.calendar.get_date()
        date = datetime.strptime(date, '%d/%m/%Y').strftime('%Y-%m-%d')
        sql_dict['date'] = date

        sql_dict['description'] = self.text_box.get('1.0', 'end').rstrip()
        sql_dict['delivered'] = self.home_type.get()
        sql_dict['name'] = self.name_e.get().rstrip()
        sql_dict['addr1'] = self.address1_e.get().rstrip()
        sql_dict['addr2'] = self.address2_e.get().rstrip()
        sql_dict['town'] = self.town_e.get().rstrip()
        sql_dict['county'] = self.county_e.get().rstrip()
        sql_dict['postcode'] = self.postcode_e.get().rstrip()
        sql_dict['phonenum'] = self.phone_num_e.get().rstrip()

        # enter the entry into Sqlite
        AdvDbQuery(self.conn, query, sql_dict, returnlist=False)

        # =============
        # Bind the homing event to the animals involved.
        # =============
        # Get the ID of the latest homing event. we just posted.
        query = """
                SELECT ID FROM Homing_Data ORDER BY ID DESC LIMIT 1
                """
        homing_id = BasicDbQuery(self.conn, query)[1][0][0]

        # add each animal to the pairing table.
        for v in self.animal_dict.values():
            query = """INSERT INTO Homing_Animal_Pairings (
                       Animal_ID,
                       Homing_Data_ID)
                       VALUES(
                       :Animal_ID,
                       :Homing_ID)"""
            sql_dict = {}
            sql_dict['Animal_ID'] = v
            sql_dict['Homing_ID'] = int(homing_id)

            # enter the entry into Sqlite
            AdvDbQuery(self.conn, query, sql_dict, returnlist=False)

        # =============
        # Ask if user wants to update individual animal pages
        # =============
        if self.home_type.get() == "home":
            home_text = "left"
        elif self.home_type.get() == "collect":
            home_text = "entered"
        msgboxtext = (
            f"Do you want to update the individual animal pages "
            f"to show that the animal has now {home_text} the rescue?")
        msgBox = messagebox.askquestion('Update Animal Pages', msgboxtext)
        if msgBox == 'yes':
            # update animal records to reflect if animal is now in rescue
            for v in self.animal_dict.values():
                if self.home_type.get() == "home":
                    home_val = 0
                elif self.home_type.get() == "collect":
                    home_val = 1

                query = """
                        UPDATE Animal
                        SET In_Rescue = :in_rescue
                        WHERE ID = :ID
                        """
                sql_dict = {}
                sql_dict['ID'] = v
                sql_dict['in_rescue'] = home_val

                AdvDbQuery(self.conn, query, sql_dict, returnlist=False)

        # close window when everything complete
        self.main_win.refresh_main_tree()
        self.close_window()

    def _add_animal(self):
        tree = self.animal_tree.tree

        # Check if anything selected in tree. Return if nothing
        results = tree.item(tree.focus())['values']
        if results == '':
            return
        # Save selected item in tree
        animal_id = results[0]
        add_name = results[1]

        # Check if animal already in list. If it is, return
        if animal_id in self.animal_dict.values():
            return

        #  Get next available row id (for if animals are removed and readded)
        button_id = self._get_next_row_id()  # returns 999 if already exist
        if button_id == 999:
            return
        else:
            self.animal_dict[button_id] = animal_id

        # ===========
        # Build the actual visible row now.
        # ===========
        # Short string of button id to make the below simpler
        ids = str(button_id)

        # Create a new master frame for row
        setattr(self, "rowmasterf" + ids, ttk.Frame(self.animal_frame))

        # set as local var so can be used below without being a mess
        masterf = getattr(self, "rowmasterf" + ids)
        masterf.pack(side="top", fill="x", ipady=1)

        # Create the widgets:
        # The remove button
        setattr(
            self, "rowb" + ids,
            ttk.Button(masterf,
                       text="-",
                       width="2",
                       command=lambda: self._remove_animal(button_id)))
        getattr(self, "rowb" + ids).pack(side="left")

        # The label
        setattr(self, "rowl" + ids,
                ttk.Label(masterf, text=str(animal_id) + ": " + add_name))
        getattr(self, "rowl" + ids).pack(side="left")

    def _remove_animal(self, rem_id):
        ids = str(rem_id)
        getattr(self, "rowmasterf" + ids).destroy()
        del self.animal_dict[rem_id]

    def _get_next_row_id(self):
        for i in range(16):  # Max 16 entries
            if i not in self.animal_dict:
                return i
        return 999

    def refresh_animal_data(self):
        md_query = "SELECT * FROM Animal_ID_View"
        if self.in_rescue_var.get() == 1:
            md_query += "_Active"
        md = BasicDbQuery(self.conn, md_query)
        self.animal_tree.refresh_data(md[1])

    def close_window(self):
        self.master.destroy()
예제 #27
0
class MedicalEntryWindow():
    def __init__(self, master, conn, main_win):
        self.conn = conn
        self.master = master
        self.med_dict = {}          # dictionary of button ID's and animal ids
        self.master.withdraw()      # Hide window
        self.master.wm_title("Medical Entries")
        CenterWindow(self.master)
        self.main_win = main_win    # Used for comunicating with parent window.
        self._build_frames()
        self._build_widgets()
        self.master.deiconify()     # show window
        self.popup = False  # Check used later to see if popup created.

    def _build_frames(self):
        # Right frame
        self.right_frame = ttk.Frame(self.master, width="200")
        self.right_frame.pack_propagate(0)
        self.right_frame.pack(side="right", fill="y")

        # - Add button frame
        self.add_frame = ttk.Frame(self.right_frame)
        self.add_frame.pack(side="top", fill="x")

        # - In-Rescue checkbox frame
        self.in_rescue_frame = ttk.Frame(self.right_frame)
        self.in_rescue_frame.pack(side="top", fill="x", anchor="w")

        # - Animal tree frame
        self.animal_tree_frame = ttk.Frame(self.right_frame)
        self.animal_tree_frame.pack(side="top", fill="both", expand="True")

        # - Add/Cancel buttons frame
        self.buttons_frame = ttk.Frame(self.right_frame)
        self.buttons_frame.pack(side="bottom", expand=True,
                                fill="x", anchor="s")

        # Left frame
        self.left_frame = ttk.Frame(self.master)
        self.left_frame.pack(side="left", fill="both", expand=True)

        # - Header frame
        self.header_frame = ttk.Frame(self.left_frame)
        self.header_frame.pack(side="top", anchor="w", fill="x")

        # -- Calender frame
        self.cal_frame = ttk.Frame(self.header_frame, width="300")
        self.cal_frame.pack(side="right", fill="y")

        # - Medical entries frame
        self.med_frame = ttk.Frame(self.left_frame)
        self.med_frame.pack(side="top", fill="both", expand=True)

    def _build_widgets(self):
        # Right frame items
        # - Add button
        self.add_button = ttk.Button(self.add_frame, text="Add Animal",
                                     command=self._add_animal)
        self.add_button.pack(side="top", anchor="n", fill="x")

        # - In-Rescue checkbox
        self.in_rescue_var = tk.IntVar()
        self.in_rescue = ttk.Checkbutton(self.in_rescue_frame,
                                         text="Only show animals in rescue: ",
                                         variable=self.in_rescue_var,
                                         command=self.refresh_animal_data)
        self.in_rescue.pack(side="left", anchor="w")
        self.in_rescue_var.set(1)

        # - Build animal tree.
        animal_query = "SELECT * FROM Animal_ID_View"
        if self.in_rescue_var.get() == 1:
            animal_query += "_Active"
        md = BasicDbQuery(self.conn, animal_query)
        self.animal_tree = TreeBuild(self.animal_tree_frame,
                                     search=True,
                                     data=md[1],
                                     headings=md[0])
        self.animal_tree.tree.bind(
            "<Double-1>",
            lambda c: self._add_animal())

        # cancel / submit button
        self.submit = ttk.Button(self.buttons_frame, text="Submit",
                                 command=self._submit_records)
        self.submit.pack(side="left", fill="x")
        self.cancel = ttk.Button(self.buttons_frame, text="Cancel",
                                 command=self.close_window)
        self.cancel.pack(side="right", fill="x")

        # Header frame items
        # - heading label
        heading = ttk.Label(self.header_frame, text="Medical Entries",
                            font=self.main_win.font_title)
        heading.pack(side="left", anchor="nw", padx=10)

        # -- Calendar frame items
        # -- Calandar
        self.calendar = Calendar(self.cal_frame)
        self.calendar.pack(side="top", anchor="n")

    def _add_animal(self):
        tree = self.animal_tree.tree
        results = tree.item(tree.focus())['values']
        if results == '':
            return
        animal_id = results[0]
        add_name = results[1]

        # Sort out next buttons/frame ID
        button_id = self._get_next_row_id()     # returns 999 if maxed out
        if button_id == 999:
            return
        else:
            self.med_dict[button_id] = animal_id

        # String of button id and shortening name for creating attributes
        ids = str(button_id)
        # ================ Frames
        # Create new master framer for row
        setattr(self, "medmasterf" + ids, ttk.Frame(self.med_frame,
                                                    style="grey.TFrame"))
        # set as local var so can be used below
        medmasterf = getattr(self, "medmasterf" + ids)
        getattr(self, "medmasterf" + ids).pack(side="top", fill="x", ipady=1)
        # - Create top frame
        setattr(self, "medf" + ids, ttk.Frame(medmasterf))
        # set as local var so can be used below
        medf = getattr(self, "medf" + ids)
        getattr(self, "medf" + ids).pack(side="top", fill="x")
        # - Create 2nd frame
        setattr(self, "medf2" + ids, ttk.Frame(medmasterf))
        # set as local var so can be used below
        medf2 = getattr(self, "medf2" + ids)
        getattr(self, "medf2" + ids).pack(side="top", fill="x")

        # ================ Widgets
        # Create the button
        setattr(self, "medb" + ids, ttk.Button(
            medf,
            text="-",
            width="2",
            command=lambda: self._remove_animal(button_id)))
        getattr(self, "medb" + ids).pack(side="left")

        # Create Labels
        setattr(self, "medid" + ids, ttk.Label(medf, text=animal_id))
        getattr(self, "medid" + ids).pack(side="left")
        name_text = ": " + add_name + " | "
        setattr(self, "medname" + ids, ttk.Label(medf, text=name_text))
        getattr(self, "medname" + ids).pack(side="left")
        # Used when building error log on submission.
        setattr(self, "mednametext" + ids, add_name)

        # Med_type combobox
        setattr(self, "medtype" + ids, ttk.Combobox(medf, state="readonly",
                                                    values=("Vet", "Other")))
        getattr(self, "medtype" + ids).pack(side="left")
        getattr(self, "medtype" + ids).bind(
            "<<ComboboxSelected>>",
            lambda c: self._med_type_selection(button_id))

        # - (vet() Vet_Name label/combobox
        text = "| Vet Name : "
        setattr(self, "medvetnamel" + ids, ttk.Label(medf, text=text))
        vet_text = self.main_win.config['DEFAULT'].get('defaultvet')
        setattr(self, "medvetnamee" + ids, ttk.Entry(medf))
        getattr(self, "medvetnamee" + ids).insert(0, vet_text)

        # - (vet) Op type
        setattr(self, "medoptypel" + ids, ttk.Label(medf, text="| Type : "))
        setattr(self, "medoptype" + ids, ttk.Combobox(
            medf,
            state="readonly",
            values=("Chip", "Checkup", "Neuter", "Vaccination", "Other")))
        getattr(self, "medoptype" + ids).bind(
            "<<ComboboxSelected>>",
            lambda c: self._op_type_selection(button_id))

        # -- (chip) chiplabel/num
        setattr(self, "chipnuml" + ids, ttk.Label(medf, text="| Chip Num : "))
        setattr(self, "chipnume" + ids, ttk.Entry(medf))

        # Cost entry boxs *Movable and will be destoyed in certain routes.
        #                  re-create when needed.
        setattr(self, "medcostl" + ids, ttk.Label(medf, text="| Cost : "))
        setattr(self, "medcoste" + ids, ttk.Entry(medf))

        # Checkup Label
        text = "| Checkup Notes : "
        setattr(self, "medcheckupl" + ids, ttk.Label(medf2, text=text))

        # Notes Entry/label
        setattr(self, "mednotesl" + ids, ttk.Label(medf2, text="| Notes : "))
        setattr(self, "mednotese" + ids, ttk.Entry(medf2))

        # Other op type label/entry
        text = "| Procedure : "
        setattr(self, "medotheropl" + ids, ttk.Label(medf, text=text))
        setattr(self, "medotherope" + ids, ttk.Entry(medf))

        # vac type (first/second)
        text = "| Vac Type : "
        setattr(self, "medvactypel" + ids, ttk.Label(medf, text=text))
        setattr(self, "medvactype" + ids, ttk.Combobox(
            medf,
            state="readonly",
            values=("First", "Second", "Top-Up")))
        getattr(self, "medvactype" + ids).bind(
            "<<ComboboxSelected>>",
            lambda c: self._vac_type_selection(button_id))

        # vac due date + label
        text = "| Next Vac Due (YYYY-MM-DD) : "
        setattr(self, "medduedatel" + ids, ttk.Label(medf2, text=text))
        setattr(self, "medduedate" + ids, DateEntry(medf2))

        # Worm/Flea/Both label + combo
        text = "| Treatment : "
        setattr(self, "medfleatypel" + ids, ttk.Label(medf, text=text))
        setattr(self, "medfleatype" + ids, ttk.Combobox(
            medf,
            state="readonly",
            values=("Flea", "Worming", "Flea and Worming", "Other")))
        getattr(self, "medfleatype" + ids).bind(
            "<<ComboboxSelected>>",
            lambda c: self._non_vet_type_selection(button_id))

    def _get_next_row_id(self):
        for i in range(16):     # Max 30 entries
            if i not in self.med_dict:
                return i
        return 999

    def _remove_animal(self, rem_id):
        ids = str(rem_id)
        getattr(self, "medmasterf" + ids).destroy()
        del self.med_dict[rem_id]

    # =========
    # Functions for controlling row contents when options selected
    # =========
    def _med_type_selection(self, button_id):
        ids = str(button_id)
        option = getattr(self, "medtype" + ids).get()
        # unpack everything first :
        getattr(self, "medvetnamel" + ids).pack_forget()
        getattr(self, "medvetnamee" + ids).pack_forget()
        getattr(self, "medoptypel" + ids).pack_forget()
        getattr(self, "medoptype" + ids).set("")    # trigger op_type below
        getattr(self, "medoptype" + ids).event_generate("<<ComboboxSelected>>")
        getattr(self, "medoptype" + ids).pack_forget()
        getattr(self, "medfleatypel" + ids).pack_forget()
        getattr(self, "medfleatype" + ids).pack_forget()

        if option == "Vet":
            # Pack vet options
            getattr(self, "medvetnamel" + ids).pack(side="left")
            getattr(self, "medvetnamee" + ids).pack(side="left")
            getattr(self, "medoptypel" + ids).pack(side="left")
            getattr(self, "medoptype" + ids).pack(side="left")
        elif option == "Other":
            getattr(self, "medfleatypel" + ids).pack(side="left")
            getattr(self, "medfleatype" + ids).pack(side="left")

    def _op_type_selection(self, button_id):
        ids = str(button_id)
        option = getattr(self, "medoptype" + ids).get()
        medf = getattr(self, "medf" + ids)
        medf2 = getattr(self, "medf2" + ids)
        # unpack everything first
        getattr(self, "chipnuml" + ids).pack_forget()
        getattr(self, "chipnume" + ids).pack_forget()
        getattr(self, "medcostl" + ids).pack_forget()
        getattr(self, "medcheckupl" + ids).pack_forget()
        getattr(self, "mednotese" + ids).pack_forget()
        getattr(self, "mednotesl" + ids).pack_forget()
        getattr(self, "medotheropl" + ids).pack_forget()
        getattr(self, "medotherope" + ids).pack_forget()
        getattr(self, "medvactype" + ids).set("")    # trigger op_type below
        getattr(self, "medvactype" + ids).event_generate(
            "<<ComboboxSelected>>")
        getattr(self, "medvactype" + ids).pack_forget()
        getattr(self, "medvactypel" + ids).pack_forget()
        # destroy items that need to be moved
        getattr(self, "medcostl" + ids).destroy()
        getattr(self, "medcoste" + ids).destroy()
        medf2.pack_forget()

        if option == "Chip":
            # only pack the frame if needed
            medf2.pack(side="top", fill="x")
            getattr(self, "chipnuml" + ids).pack(side="left")
            getattr(self, "chipnume" + ids).pack(side="left")
            # re-create it in 2nd row
            setattr(self, "medcostl" + ids, ttk.Label(medf2, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf2))
            getattr(self, "medcoste" + ids).pack(side="left")
        elif option == "Checkup":
            setattr(self, "medcostl" + ids, ttk.Label(medf, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf))
            getattr(self, "medcoste" + ids).pack(side="left")
            # only pack the frame if needed
            medf2.pack(side="top", fill="x")
            getattr(self, "medcheckupl" + ids).pack(side="left")
            getattr(self, "mednotese" + ids).pack(side="left",
                                                  fill="x",
                                                  expand=True)
        elif option == "Neuter":
            setattr(self, "medcostl" + ids, ttk.Label(medf, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf))
            getattr(self, "medcoste" + ids).pack(side="left")
        elif option == "Other":
            getattr(self, "medotheropl" + ids).pack(side="left")
            getattr(self, "medotherope" + ids).pack(side="left",
                                                    fill="x",
                                                    expand=True)
            # only pack the frame if needed
            medf2.pack(side="top", fill="x")
            setattr(self, "medcostl" + ids, ttk.Label(medf2, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf2))
            getattr(self, "medcoste" + ids).pack(side="left")
            getattr(self, "mednotesl" + ids).pack(side="left")
            getattr(self, "mednotese" + ids).pack(side="left",
                                                  fill="x",
                                                  expand=True)
        elif option == "Vaccination":
            getattr(self, "medvactypel" + ids).pack(side="left")
            getattr(self, "medvactype" + ids).pack(side="left")

    def _vac_type_selection(self, button_id):
        ids = str(button_id)
        option = getattr(self, "medvactype" + ids).get()
        medf2 = getattr(self, "medf2" + ids)
        # unpack everything first
        getattr(self, "medduedate" + ids).pack_forget()
        getattr(self, "medduedatel" + ids).pack_forget()
        getattr(self, "medcostl" + ids).destroy()
        getattr(self, "medcoste" + ids).destroy()
        medf2.pack_forget()

        if option in ("First", "Second", "Top-Up"):
            # only pack the frame if needed
            medf2.pack(side="top", fill="x")
            setattr(self, "medcostl" + ids, ttk.Label(medf2, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf2))
            getattr(self, "medcoste" + ids).pack(side="left")
            getattr(self, "medduedatel" + ids).pack(side="left")
            getattr(self, "medduedate" + ids).pack(side="left")
        # Inserting Dates into datebox.
        due_date_text = datetime.strptime(self.calendar.get_date(), '%d/%m/%Y')
        if option == "First":
            due_date_text += timedelta(days=28)
            due_date_text = due_date_text.strftime('%Y-%m-%d')
            getattr(self, "medduedate" + ids).delete(0, 'end')
            getattr(self, "medduedate" + ids).insert(0, due_date_text)
        elif option in ("Second", "Top-Up"):
            due_date_text += timedelta(days=365)
            due_date_text = due_date_text.strftime('%Y-%m-%d')
            getattr(self, "medduedate" + ids).delete(0, 'end')
            getattr(self, "medduedate" + ids).insert(0, due_date_text)

    def _non_vet_type_selection(self, button_id):
        ids = str(button_id)
        option = getattr(self, "medfleatype" + ids).get()
        medf = getattr(self, "medf" + ids)
        # unpack everything first
        getattr(self, "medcostl" + ids).destroy()
        getattr(self, "medcoste" + ids).destroy()
        getattr(self, "medotheropl" + ids).pack_forget()
        getattr(self, "medotherope" + ids).pack_forget()

        if option in ('Flea', 'Worming', 'Flea and Worming'):
            setattr(self, "medcostl" + ids, ttk.Label(medf, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf))
            getattr(self, "medcoste" + ids).pack(side="left")
        elif option == "Other":
            getattr(self, "medotheropl" + ids).pack(side="left")
            getattr(self, "medotherope" + ids).pack(side="left")
            setattr(self, "medcostl" + ids, ttk.Label(medf, text="| Cost : "))
            getattr(self, "medcostl" + ids).pack(side="left")
            setattr(self, "medcoste" + ids, ttk.Entry(medf))
            getattr(self, "medcoste" + ids).pack(side="left")
    # =========
    # End of functions
    # =========

    def _submit_records(self):
        if not self._check_errors() or len(self.med_dict) == 0:
            return

        # =============
        # Building up the dictionary used to generate SQL
        # =============
        date = self.calendar.get_date()
        date = datetime.strptime(date, '%d/%m/%Y').strftime('%Y-%m-%d')
        for k, v in self.med_dict.items():
            # get initial values
            animal_id = int(v)
            ids = str(k)        # widget ID as STR for getting values
            value_dict = {}     # empty dict used to contain values for SQL

            # Set chip-update flag to false
            chip_update = False

            # Add Animal
            value_dict['Animal_ID'] = animal_id

            # Add Date
            value_dict['Date'] = date

            # - Check first combobox Vet/Other
            combo = getattr(self, "medtype" + ids).get()
            if combo == "Vet":
                value_dict['Medical_Type'] = combo
                # Add VetName
                vetname = getattr(self, "medvetnamee" + ids).get()
                value_dict['Vet_Name'] = vetname

                # Check vet appointment type
                app_type = getattr(self, "medoptype" + ids).get()
                if app_type == "Chip":
                    # Add Medical Type:
                    value_dict['Procedure'] = app_type

                    # enable chip updating after medical entry
                    chip_update = True

                    # Add chip number
                    chip_num = getattr(self, "chipnume" + ids).get()
                    value_dict['Chip_Num'] = chip_num

                    # Add Cost
                    cost = getattr(self, "medcoste" + ids).get()
                    value_dict['Cost'] = float(cost)

                # If Checkup
                elif app_type == "Checkup":
                    # Add Medical Type:
                    value_dict['Procedure'] = app_type

                    # Add Cost
                    cost = getattr(self, "medcoste" + ids).get()
                    value_dict['Cost'] = float(cost)

                    # Add Notes
                    notes = getattr(self, "mednotese" + ids).get()
                    value_dict['Notes'] = notes

                # If Neuter
                elif app_type == "Neuter":
                    # Add Medical Type:
                    value_dict['Procedure'] = app_type

                    # Add Cost
                    cost = getattr(self, "medcoste" + ids).get()
                    value_dict['Cost'] = float(cost)

                # If Other
                elif app_type == "Other":
                    # Add Medical Type:
                    procedure = getattr(self, "medotherope" + ids).get()
                    value_dict['Procedure'] = procedure

                    # Add Cost
                    cost = getattr(self, "medcoste" + ids).get()
                    value_dict['Cost'] = float(cost)

                    # Add Notes
                    notes = getattr(self, "mednotese" + ids).get()
                    value_dict['Notes'] = notes

                # If vaccination
                elif app_type == "Vaccination":
                    # Add Medical Type:
                    procedure = "Vaccination"
                    value_dict['Procedure'] = procedure

                    # vac-type
                    vac_type = getattr(self, "medvactype" + ids).get()
                    if vac_type == 'First':
                        value_dict['Vac_Type'] = 1
                    elif vac_type == 'Second':
                        value_dict['Vac_Type'] = 2
                    elif vac_type == 'Top-Up':
                        value_dict['Vac_Type'] = 3

                    # Add Cost
                    cost = getattr(self, "medcoste" + ids).get()
                    value_dict['Cost'] = float(cost)

                    # Due date
                    due_date = getattr(self, "medduedate" + ids).get_date()
                    due_date = due_date.strftime('%Y-%m-%d')
                    value_dict['Due_Date'] = due_date

            # If Other
            elif combo == "Other":
                value_dict['Medical_Type'] = combo

                # Add Cost
                cost = getattr(self, "medcoste" + ids).get()
                value_dict['Cost'] = float(cost)

                # Check other-type box
                othertype = getattr(self, "medfleatype" + ids).get()
                if othertype in ('Flea', 'Worming', 'Flea and Worming'):
                    value_dict['Procedure'] = othertype

                elif othertype == 'Other':
                    procedure = getattr(self, "medotherope" + ids).get()
                    value_dict['Procedure'] = procedure

            # =============
            # Using Dictionary to generate insert str
            # =============
            sqlstr = 'INSERT INTO Medical (\n'
            # Adding column names
            for k, v in value_dict.items():
                sqlstr += str(k) + ',\n'
            sqlstr = sqlstr[:len(sqlstr) - 2]   # remove final command&newline

            sqlstr += ')\nVALUES (\n'

            # Adding value headings.
            for k, v in value_dict.items():
                sqlstr += ':' + str(k) + ',\n'
            sqlstr = sqlstr[:len(sqlstr) - 2]   # remove final command&newline

            sqlstr += ')'
            AdvDbQuery(self.conn, sqlstr, value_dict, returnlist=False)

            # =============
            # Updating chip info if necesarry
            # =============
            if chip_update:
                sqlstr = """
                         UPDATE Animal
                         SET Chip_Num = :Chip_Num
                         WHERE ID = :ID
                         """

                chip_dict = {}
                chip_dict['Chip_Num'] = chip_num
                chip_dict['ID'] = animal_id
                AdvDbQuery(self.conn, sqlstr, chip_dict, returnlist=False)
            self.main_win.refresh_main_tree()
        self.close_window()

    def close_window(self):
        self.master.destroy()

    def refresh_animal_data(self):
        md_query = "SELECT * FROM Animal_ID_View"
        if self.in_rescue_var.get() == 1:
            md_query += "_Active"
        md = BasicDbQuery(self.conn, md_query)
        self.animal_tree.refresh_data(md[1])

    def _check_errors(self):
        """Returns True if no errors found.
        Otherwise returns False and opens a pop-up box with errors found"""
        error = False
        err_text = ''
        for row, key in enumerate(self.med_dict):
            # get initial values
            rownum = row + 1
            ids = str(key)                                      # row-ID
            animal_name = getattr(self, "mednametext" + ids)    # Animal Name

            # row-error variables.
            row_error = False
            row_error_header = f"Row {rownum}: Errors Found ({animal_name})\n"
            row_error_text = ''

            # - Check first combobox Vet/Other
            combo = getattr(self, "medtype" + ids).get()
            if combo == "Vet":
                # Check if VetName supplied
                vetname = getattr(self, "medvetnamee" + ids).get()
                if vetname == '':
                    row_error = True
                    row_error_text += '  -  Vet name missing\n'

                # Check vet appointment type
                app_type = getattr(self, "medoptype" + ids).get()
                # If blank
                if app_type == "":
                    row_error = True
                    row_error_text += '  -  Select an appointment type\n'
                # If Chip Num
                elif app_type == "Chip":
                    # Check chip number
                    chip_num = getattr(self, "chipnume" + ids).get()
                    if chip_num == '':
                        row_error = True
                        row_error_text += '  -  Enter the chip number\n'
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0)\n'
                # If Checkup
                elif app_type == "Checkup":
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0)\n'
                # If Neuter
                elif app_type == "Neuter":
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0)\n'
                # If Other
                elif app_type == "Other":
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0)\n'
                    # Check Procedure
                    procedure = getattr(self, "medotherope" + ids).get()
                    if procedure == '':
                        row_error = True
                        row_error_text += '  -  Enter a procedure\n'
                # If vaccination
                elif app_type == "Vaccination":
                    # Check vac-type box
                    vac_type = getattr(self, "medvactype" + ids).get()
                    if vac_type == '':
                        row_error = True
                        row_error_text += '  -  Select a vaccination type\n'
                    else:
                        # Check cost
                        cost = getattr(self, "medcoste" + ids).get()
                        if cost == '':
                            row_error = True
                            row_error_text += '  -  Enter a cost (even 0)\n'
                        # Check Date is valid
                        valid_date = getattr(self, "medduedate" + ids).is_valid
                        if not valid_date:
                            row_error = True
                            row_error_text += '  -  Enter a valid date\n'
            # If Other
            elif combo == "Other":
                # Check other-type combobox
                # If blank
                othertype = getattr(self, "medfleatype" + ids).get()
                if othertype == '':
                    row_error = True
                    row_error_text += '  -  Pick a treatment type\n'
                # if Flear or worming
                elif othertype in ('Flea', 'Worming', 'Flea and Worming'):
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0 is ok)\n'
                elif othertype == 'Other':
                    # Check cost
                    cost = getattr(self, "medcoste" + ids).get()
                    if cost == '':
                        row_error = True
                        row_error_text += '  -  Enter a cost (even 0 is ok)\n'
                    # Check Procedure
                    procedure = getattr(self, "medotherope" + ids).get()
                    if procedure == '':
                        row_error = True
                        row_error_text += '  -  Enter the procedure\n'
            elif combo == "":
                row_error = True
                row_error_text += '  -  Select an item in the drop-down box\n'

            # If errors have been detected. add the error text to the log.
            if row_error:
                error = True
                err_text += row_error_header + row_error_text + '\n'
        if error:
            PopUp(self.master,
                  'MedicalEntries',
                  heading="Errors found in entries",
                  text=err_text)
            return False
        else:
            return True
class DateAndTimePopupWindow(GuiBase):
    EMPTY_FRAME1 = 'DATE_AND_TIME_POPUP_EMPTY_FRAME1'
    EMPTY_FRAME2 = 'DATE_AND_TIME_POPUP_EMPTY_FRAME2'

    WINDOW = 'DATA_AND_TIME_POPUP_WINDOW'
    CALENDAR_FRAME = 'DATE_AND_TIME_POPUP_CALENDAR_FRAME'
    TIME_FRAME = 'DATE_AND_TIME_POPUP_TIME_FRAME'
    OK_AND_CANCEL_FRAME = 'DATE_AND_TIME_POPUP_OK_AND_CANCEL_FRAME'

    __date_ms: int
    __year: int
    __month: int
    __day: int
    __hour: int
    __min: int
    __sec: int

    __calendar: Calendar = None
    __hours_combobox: Combobox = None
    __minutes_combobox: Combobox = None
    __seconds_combobox: Combobox = None

    def __init__(self, date_ms: int = -1):
        super().__init__()
        self.__set_date(date_ms)
        self.set_window(self.WINDOW, Toplevel())
        self._add_to_parent_frames_dict(self.get_window(self.WINDOW),
                                        self.WINDOW)
        self.get_window(self.WINDOW).resizable(0, 0)
        self.get_window(self.WINDOW).title('Set Data and Time')
        self.__add_calendar()
        self.__add_empty_frame1()
        self.__add_time_comboboxes()
        self.__add_empty_frame2()
        self.__add_ok_and_cancel_buttons()

    def open_popup(self):
        self.get_window(self.WINDOW).mainloop()

    def close_window(self):
        self.destroy_window(self.WINDOW)

    @property
    def date_ms(self) -> int:
        return self.__date_ms

    def __add_empty_frame1(self):
        self._add_frame_to_parent_frame_grid(self.EMPTY_FRAME1,
                                             self.WINDOW,
                                             FrameGridPositionEnum.NEXT_ROW,
                                             height=15)

    def __add_empty_frame2(self):
        self._add_frame_to_parent_frame_grid(self.EMPTY_FRAME2,
                                             self.WINDOW,
                                             FrameGridPositionEnum.NEXT_ROW,
                                             height=15)

    def __add_ok_and_cancel_buttons(self):
        frame = self._add_frame_to_parent_frame_grid(
            self.OK_AND_CANCEL_FRAME,
            self.WINDOW,
            FrameGridPositionEnum.NEXT_ROW,
            pady=self.PAD_Y)
        ok_button = self._add_button_to_frame_grid(frame, 'OK', 0, 0)
        ok_button.bind('<Button-1>', self.__ok_button_click)
        cancel_button = self._add_button_to_frame_grid(frame, 'Cancel', 0, 1)
        cancel_button.bind('<Button-1>', self.__cancel_button_click)

    def __add_time_comboboxes(self):
        frame = self._add_frame_to_parent_frame_grid(
            self.TIME_FRAME,
            self.WINDOW,
            FrameGridPositionEnum.NEXT_ROW,
            padx=self.PAD_X,
            pady=self.PAD_Y)
        self._add_label_to_frame_grid(frame,
                                      'Hour: ',
                                      0,
                                      0,
                                      sticky=GridPositionEnum.W)
        hours_data = tuple([h for h in range(24)])
        self.__hours_combobox = self._add_combobox_to_frame_grid(
            frame, hours_data, 0, 1, width=3, current=self.__hour)
        self._add_label_to_frame_grid(frame,
                                      'Minute: ',
                                      0,
                                      2,
                                      sticky=GridPositionEnum.W)
        minutes_data = tuple([m for m in range(60)])
        self.__minutes_combobox = self._add_combobox_to_frame_grid(
            frame, minutes_data, 0, 3, width=3, current=self.__min)
        self._add_label_to_frame_grid(frame,
                                      'Second: ',
                                      0,
                                      4,
                                      sticky=GridPositionEnum.W)
        seconds_data = tuple([s for s in range(60)])
        self.__seconds_combobox = self._add_combobox_to_frame_grid(
            frame, seconds_data, 0, 5, width=3, current=self.__sec)

    def __add_calendar(self):
        frame = self._add_frame_to_parent_frame_grid(
            self.CALENDAR_FRAME,
            self.WINDOW,
            FrameGridPositionEnum.NEXT_ROW,
            pady=self.PAD_Y)

        self.__calendar = Calendar(frame.frame,
                                   selectmode="day",
                                   year=self.__year,
                                   month=self.__month,
                                   day=self.__day)

        self.__calendar.grid(row=0, column=0, sticky=GridPositionEnum.N.value)

    def __ok_button_click(self, event):
        date_split = self.__calendar.get_date().split('/')
        day = int(date_split[1])
        month = int(date_split[0])
        year = int(f'20{date_split[2]}')

        date = datetime(year=year,
                        month=month,
                        day=day,
                        hour=self.__hours_combobox.current(),
                        minute=self.__minutes_combobox.current(),
                        second=self.__seconds_combobox.current())

        self.__date_ms = TimeUtil.date_time_to_date_ms(date)

        self.quit_window(self.WINDOW)

    def __cancel_button_click(self, event):
        self.destroy_window(self.WINDOW)

    def __set_date(self, date_ms: int):
        if date_ms == -1:
            date_ms = TimeUtil.get_current_date_ms()
        self.__date_ms = date_ms

        date = TimeUtil.date_ms_to_date_time(date_ms)

        self.__year = date.year
        self.__month = date.month
        self.__day = date.day
        self.__hour = date.hour
        self.__min = date.minute
        self.__sec = date.second
class AddNewProjection(Tk):
    def __init__(self, userdetails={}):
        Tk.__init__(self)

        self.userdetails = userdetails

        self.listOfMovies = getAllMovie()
        self.listOfMoviesNames = []

        self.listOfAuditorium = getAllScreens()
        self.listOfAuditoriumIDS = []

        self.selectedStartDate = str(datetime.datetime.today().date())

        if self.listOfMovies == None:
            messagebox.showerror(
                'Error',
                "No Moive Exits ,Please add movie before adding projection")
            self.destroy()

        elif self.listOfAuditorium == None:
            messagebox.showerror(
                'Error',
                "No Auditorium Exits ,Please add Auditorium before adding projection"
            )
            self.destroy()
        else:
            for row in self.listOfMovies:
                self.listOfMoviesNames.append(row[1])

            for row in self.listOfAuditorium:
                self.listOfAuditoriumIDS.append(row[0])
            self.onCreate()

    def onCreate(self):
        HEIGHT = 800
        WIDTH = 800
        canvas = Canvas(self, height=HEIGHT, width=WIDTH)
        canvas.pack()
        frame = Frame(canvas, bg="grey")
        frame.place(relx=0.01, rely=0.01, relwidth=0.98, relheight=0.98)

        Label(frame, text="Add New Projection",
              font=("Helvetica", 12)).grid(row=0,
                                           columnspan=2,
                                           pady=15,
                                           padx=15)

        Label(frame, text="Select Movie: ").grid(row=1, pady=10)
        Label(frame, text="Select Auditorium/Screen: ").grid(row=2, pady=10)
        Label(frame, text="Select Date : ").grid(row=3, pady=10)
        Label(frame, text="Select Start Time: ").grid(row=4, pady=10)
        Label(frame, text="Select End Time: ").grid(row=5, pady=10)

        self.moviesChkbox = ttk.Combobox(master=frame)
        self.moviesChkbox['values'] = self.listOfMoviesNames
        self.moviesChkbox.grid(row=1, column=1, pady=10)

        self.auditoriumChkbox = ttk.Combobox(master=frame)
        self.auditoriumChkbox['values'] = self.listOfAuditoriumIDS
        self.auditoriumChkbox.grid(row=2, column=1, pady=10)

        self.date_picker = Calendar(master=frame,
                                    date_pattern='y-mm-dd',
                                    mindate=datetime.datetime.today())
        self.date_picker.bind('<<CalendarSelected>>', self.setStartDate)
        self.date_picker.grid(row=3, column=1, pady=10)

        self.startVariable = StringVar(master=frame, value="HH:MM:SS")
        self.endVariable = StringVar(master=frame, value="HH:MM:SS")

        self.startTime_entry = Entry(master=frame,
                                     textvariable=self.startVariable)
        self.endTime_entry = Entry(master=frame, textvariable=self.endVariable)

        self.startTime_entry.grid(row=4, column=1, pady=10)
        self.endTime_entry.grid(row=5, column=1, pady=10)

        Label(frame,
              text="24Hrs Format (%H:%M:%S) eg (16:30:00)").grid(row=4,
                                                                 column=2,
                                                                 pady=10)
        Label(frame,
              text="24Hrs Format (%H:%M:%S) eg(12:00:00)").grid(row=5,
                                                                column=2,
                                                                pady=10)

        submit_btn = Button(master=frame,
                            text=" Submit ",
                            command=self.onSubmitPressed)
        submit_btn.grid(row=6, column=0, columnspan=3, pady=10)

    def onSubmitPressed(self):
        if self.selectedStartDate == None or self.startVariable.get(
        ) == "HH:MM:SS" or self.endVariable.get() == "HH:MM:SS":
            messagebox.showerror(
                "Invalid Input",
                "All fields are mandatory plaese fill them correctly")

        else:
            startdatetime_str = str(self.selectedStartDate) + " " + str(
                self.startVariable.get())
            enddatetime_str = str(self.selectedStartDate) + " " + str(
                self.endVariable.get())

            try:
                startdatetime = datetime.datetime.strptime(
                    startdatetime_str, "%Y-%m-%d %H:%M:%S")
                enddatetime = datetime.datetime.strptime(
                    enddatetime_str, "%Y-%m-%d %H:%M:%S")
            except:
                messagebox.showerror("Invalid Time Input",
                                     "PLease enter times carefully")
                return
            movieID = self.listOfMovies[self.moviesChkbox.current()][0]
            auditorium_ID = self.listOfAuditoriumIDS[
                self.auditoriumChkbox.current()]
            available_seats = self.listOfAuditorium[
                self.auditoriumChkbox.current()][1]

            msg = AddNewProjectionToDB(movie_ID=movieID,
                                       auditorium_ID=auditorium_ID,
                                       startTime=startdatetime,
                                       endTime=enddatetime,
                                       available_seats=available_seats,
                                       total_seats=available_seats)
            if msg[0] == 0:
                messagebox.showinfo("Success", msg[1])
                self.destory()

            if msg[0] == 1:
                messagebox.showerror("Error", msg[1])

    def setStartDate(self, *args):
        self.selectedStartDate = self.date_picker.get_date()
        print(self.selectedStartDate)

    def start(self):
        self.mainloop()

    def destory(self):
        self.destroy()
예제 #30
0
class AnimalWindow():
    def __init__(self, master, conn, main_win,
                 window_type="new", animal_id=""):
        self.conn = conn
        self.master = master
        self.master.withdraw()      # Hide window
        CenterWindow(self.master)
        self.animal_id = animal_id
        self.main_win = main_win
        self.type = window_type
        self._Setup_fonts()
        self._build_frames()
        self._build_widgets()
        if animal_id != "" and window_type == "edit":
            self._populate_data(conn, self.animal_id)
        self.master.deiconify()     # Show window

    def _Setup_fonts(self):
        # Title Font settings
        self.font_title = tkfont.Font(size=30, weight='bold')

    def _build_frames(self):
        # Right Frame
        self.right_frame = ttk.Frame(self.master, width="300")
        self.right_frame.pack(side="right", fill="both")

        # - Image frame
        self.image_frame = ttk.Frame(self.right_frame, width="300",
                                     height="300", style="grey.TLabel")
        self.image_frame.pack(side="top", fill="x")

        # - Set image frame
        self.image_button_frame = ttk.Frame(self.right_frame)
        self.image_button_frame.pack(side="top", anchor="c")

        # - Notes header frame
        self.note_header_frame = ttk.Frame(self.right_frame)
        self.note_header_frame.pack(side="top", fill="x")

        # - Notes frame
        self.notes_frame = ttk.Frame(self.right_frame)
        self.notes_frame.pack(side="top", fill="both", anchor="n")

        # - Buttons frame
        self.buttons_frame = ttk.Frame(self.right_frame)
        self.buttons_frame.pack(side="bottom", expand=True,
                                fill="x", anchor="s")

        # -- Left button frame
        self.left_button_frame = ttk.Frame(self.buttons_frame)
        self.left_button_frame.pack(side="left", expand=True,
                                    fill="both", anchor="w")

        # -- Right button frame
        self.right_button_frame = ttk.Frame(self.buttons_frame)
        self.right_button_frame.pack(side="right", expand=True,
                                     fill="both", anchor="e")

        # Left frame
        self.left_frame = ttk.Frame(self.master)
        self.left_frame.pack(side="left", expand=True, fill="both")

        # - Title frame
        self.title_frame = ttk.Frame(self.left_frame)
        self.title_frame.pack(side="top", fill="x", ipady=10)

        # - Data frame (for dob, colour etc)
        self.data_frame = ttk.Frame(self.left_frame)
        self.data_frame.pack(side="top", fill="x")

        # -- Setting column list
        self.data_col = []
        # -- Column setup
        self.col_padd = 5
        self.col_paddl = self.col_padd + 1
        num_of_cols = 2     # Increase to add columns.
        for col in range(num_of_cols):
            self.data_col.insert(col, [0, 1])
            self.data_col[col][0] = ttk.Frame(self.data_frame)
            self.data_col[col][0].pack(side="left", ipadx=5, anchor="n")
            self.data_col[col][1] = ttk.Frame(self.data_frame)
            self.data_col[col][1].pack(side="left", ipadx=5, anchor="n")

        # -- Dob column
        self.dob_col = ttk.Frame(self.data_frame)
        self.dob_col.pack(side="left", ipadx=5, anchor="n")

        # --- Dob known holding frame
        self.dob_holding_frame = ttk.Frame(self.dob_col)
        self.dob_holding_frame.pack(side="top", anchor="n", fill="x")
        # ---- Dob known frames
        self.dob_known_col = [0, 1]
        self.dob_known_col[0] = ttk.Frame(self.dob_holding_frame)
        self.dob_known_col[0].pack(side="left", ipadx=5, anchor="n")
        self.dob_known_col[1] = ttk.Frame(self.dob_holding_frame)
        self.dob_known_col[1].pack(side="left", ipadx=5, anchor="n")

        # - Central frame
        self.central_frame = ttk.Frame(self.left_frame, style="brown.TFrame")
        self.central_frame.pack(side="top", fill="both", expand=True)

        # -- Medical history frame
        self.med_hist_frame = ttk.Frame(self.central_frame)
        self.med_hist_frame.pack_propagate(0)
        self.med_hist_frame.pack(side="top", fill="both", expand=True)

        # -- homing history frame
        self.home_hist_frame = ttk.Frame(self.central_frame)
        self.home_hist_frame.pack_propagate(0)
        self.home_hist_frame.pack(side="top", fill="both", expand=True)

    def _build_widgets(self):
        # ===============
        # Title widgets
        # ===============
        # - Title Labels
        self.id_label = ttk.Label(
            self.title_frame,
            font=self.font_title)
        self.id_label.pack(side="left", padx=5)
        self.name_entry = ttk.Entry(self.title_frame, font=self.font_title)
        self.name_entry.pack(side="left")

        # ===============
        # Right frame, notes widgets
        # ===============
        # - image
        rel_path = 'images\\thumbnails\\' + str(self.animal_id) + '.png'
        if check_rel_file(rel_path):
            thumbnail_path = rel_path
        else:
            thumbnail_path = get_full_path("config\\default_thumbnail.png")
        thumbnail_im = Image.open(thumbnail_path)
        thumbnail_ph = ImageTk.PhotoImage(thumbnail_im)
        self.thumbnail_img = ttk.Label(self.image_frame, image=thumbnail_ph)
        self.thumbnail_img.image = thumbnail_ph
        self.thumbnail_img.pack(side="top")

        # - setimage button
        set_img_button = ttk.Button(
            self.image_button_frame,
            text="Set Profile Photo",
            command=lambda c=self.animal_id: self._set_profile_image(c))
        if self.animal_id != "":
            set_img_button.pack(side="left", anchor="c", padx=3)

        # - Notes items.
        # - Notes label
        self.notes_l = ttk.Label(self.note_header_frame,
                                 text="Notes:", anchor="n")
        self.notes_l.pack(side="top", fill="x",)

        # - Notes text box
        notes_scroll = tk.Scrollbar(self.notes_frame)
        self.note_text = tk.Text(self.notes_frame, width="34")
        notes_scroll.pack(side="right", fill="y", expand=True)
        self.note_text.pack(side="right", fill="both", expand=True)
        notes_scroll.config(command=self.note_text.yview)
        self.note_text.config(yscrollcommand=notes_scroll.set)

        # ===============
        # animal data widgets
        # ===============
        # - Column 0 items
        # - Colour
        self.colour_0 = ttk.Label(self.data_col[0][0], text="Colour: ")
        self.colour_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.colour_1 = ttk.Entry(self.data_col[0][1])
        self.colour_1.pack(side="top", anchor="w", pady=self.col_padd)

        # - Sex
        self.sex_0 = ttk.Label(self.data_col[0][0], text="Sex: ", anchor="w")
        self.sex_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.sex_1 = ttk.Combobox(self.data_col[0][1], state='readonly',
                                  values=('Unknown', 'Male', 'Female'))
        self.sex_1.pack(side="top", anchor="w", pady=self.col_padd)

        # - Chip number
        self.chip_num_0 = ttk.Label(self.data_col[0][0], text="Chip Number: ")
        self.chip_num_0.pack(side="top", anchor="w", ipady=self.col_padd)
        self.chip_num_1 = ttk.Entry(self.data_col[0][1])
        self.chip_num_1.pack(side="top", anchor="w", pady=self.col_padd)

        # - Hair type
        self.hair_type_0 = ttk.Label(self.data_col[0][0],
                                     text="Hair type: ", anchor="w")
        self.hair_type_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.hair_type_1 = ttk.Combobox(self.data_col[0][1], state='readonly',
                                        values=('Short Hair', 'Long Hair'))
        self.hair_type_1.pack(side="top", anchor="w", pady=self.col_padd)

        # - In Rescue
        self.in_rescue_0 = ttk.Label(self.data_col[0][0],
                                     text="In Rescue: ", anchor="w")
        self.in_rescue_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.in_rescue_var = tk.IntVar()
        self.in_rescue_1 = ttk.Checkbutton(self.data_col[0][1],
                                           variable=self.in_rescue_var)
        self.in_rescue_1.pack(side="top", anchor="w", pady=self.col_padd)
        self.in_rescue_var.set(1)

        # - Dob columns
        # - DOB known
        self.dob_known_0 = ttk.Label(self.dob_known_col[0],
                                     text="DOB known?: ", anchor="w")
        self.dob_known_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.dob_known_1 = ttk.Combobox(self.dob_known_col[1],
                                        state='readonly',
                                        values=('No', 'Yes', 'Roughly'))
        self.dob_known_1.pack(side="top", anchor="w", pady=self.col_padd)
        self.dob_known_1.bind("<<ComboboxSelected>>", self._show_hide_date)

        # - DOB text
        self.dob_text_0 = ttk.Label(self.dob_known_col[0],
                                    text="Date of birth: ", anchor="w")
        self.dob_text_0.pack(side="top", anchor="w", ipady=self.col_paddl)
        self.dob_text_1 = ttk.Label(self.dob_known_col[1], anchor="w")
        self.dob_text_1.pack(side="top", anchor="w", ipady=self.col_padd)

        # DOB Cal
        self.dob_cal = Calendar(self.dob_col)
        self.dob_cal.pack(side="top", anchor="n", fill="x")

        # ===============
        # Medical history widgets
        # ===============
        # Medical history label
        if self.type != "new":
            sql_query = f"""
                        SELECT SUM(Cost)
                        FROM Medical
                        where Animal_ID = {self.animal_id}
                        """
            med_spend = BasicDbQuery(self.conn, sql_query)[1][0][0]
            med_spend = round(med_spend, 2)
            med_text = f"Medical History   -   Total Spend = £{med_spend}"
            med_label = ttk.Label(self.med_hist_frame, text=med_text)
            med_label['font'] = self.main_win.font_sub_title
            med_label.pack(side="top", fill="x")

            # Get medical history data from view
            sql_query = """SELECT *
                        FROM Animal_Page_Med_History
                        WHERE Animal_ID = :ID"""
            sql_dict = {'ID': self.animal_id}
            med_results = AdvDbQuery(self.conn, sql_query, sql_dict)
            med_tree = TreeBuild(self.med_hist_frame,
                                 search=True,
                                 data=med_results[1],
                                 widths=[0, 100, 50, 1300],
                                 headings=med_results[0])
            # Needed to stop linter from moaning about being un-used
            # It will be used at a later date
            med_tree

        # ===============
        # Homing history widgets
        # ===============
        # Medical history label
        if self.type != "new":
            home_label = ttk.Label(self.home_hist_frame,
                                   text="Homing History")
            home_label['font'] = self.main_win.font_sub_title
            home_label.pack(side="top", fill="x")

            # Temp table
            sql_query = """SELECT *
                        FROM Animal_Page_Homing_History
                        WHERE ID = :ID"""
            hom_results = AdvDbQuery(self.conn, sql_query, sql_dict)
            hom_tree = TreeBuild(self.home_hist_frame,
                                 search=True,
                                 data=hom_results[1],
                                 widths=[70, 40, 95, 120, 300, 100, 2000],
                                 headings=hom_results[0])
            # Needed to stop linter from moaning about being un-used
            # It will be used at a later date
            hom_tree

        # ===============
        # bottom-right save/submit widgets
        # ===============
        # Cancel / submit / save changes buttons
        self.cancel = ttk.Button(self.right_button_frame, text="Cancel",
                                 command=self.close_window)
        self.cancel.pack(side="left", anchor="w", padx=20, pady=10)
        self.submit = ttk.Button(
            self.left_button_frame,
            text="Submit",
            command=lambda c="save": self.update_database(c))
        self.save = ttk.Button(
            self.left_button_frame,
            text="Save",
            command=lambda c="edit": self.update_database(c))

        if self.type == "edit":
            self.save.pack(side="right", anchor="e", padx=20, pady=10)
        else:
            self.submit.pack(side="right", anchor="e", padx=20, pady=10)

    def _set_profile_image(self, animal_id):
        # =============
        # Fetch image
        # =============
        # Need to temporarily hide root window else it changes focus
        # when asking for file name.
        Globals.root.withdraw()

        # Ask for file
        new_image_loc = askopenfilename(filetypes=[(
            "Images", "*.jpg *.jpeg *.png")])

        # Bring animal window to front again and unhide root window
        Globals.root.deiconify()
        self.thumbnail_img.lift()
        self.thumbnail_img.focus_force()

        # =============
        # Resize image to 300px in largest dimension
        # =============
        img = cv2.imread(new_image_loc)     # load image into variable

        # Get new width and height
        w = img.shape[1]
        h = img.shape[0]
        max_dimension = 300
        if w <= h:
            nw = int(round(w / h * max_dimension, 0))
            nh = max_dimension
        else:
            nh = int(round(h / w * max_dimension, 0))
            nw = max_dimension
        dimension = (nw, nh)

        # Set new image
        new_img = cv2.resize(img, dimension, interpolation=cv2.INTER_AREA)

        # =============
        # Store image and update on window
        # =============
        # get path of new image
        rel_path = 'images\\thumbnails\\'
        rel_path += str(self.animal_id) + '.png'
        rel_folder = 'images\\thumbnails\\'

        # Check folder exists. Create if not
        check_rel_folder(rel_folder, create=True)
        # Save photo
        cv2.imwrite(rel_path, new_img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0])

        # Update image on page
        thumbnail_im = Image.open(rel_path)
        thumbnail_ph = ImageTk.PhotoImage(thumbnail_im)
        self.thumbnail_img.configure(image=thumbnail_ph)
        self.thumbnail_img.image = thumbnail_ph

    def update_database(self, sql_type=""):
        if sql_type == "":
            print("no sql type supplied")
            return

        update_dict = {}

        # Get values
        update_dict['Name'] = self.name_entry.get().rstrip()
        update_dict['Colour'] = self.colour_1.get().rstrip()
        update_dict['Sex'] = self.sex_1.get()
        update_dict['Chip'] = self.chip_num_1.get().rstrip()
        update_dict['Hair'] = self.hair_type_1.get()
        update_dict['DobKnown'] = self.dob_known_1.get()
        if update_dict['DobKnown'] != "No":
            temp_date = datetime.strptime(self.dob_cal.get_date(), '%d/%m/%Y')
            temp_date = temp_date.strftime('%Y-%m-%d')
        else:
            temp_date = ""
        update_dict['Dob'] = temp_date
        update_dict['Notes'] = self.note_text.get('1.0', 'end').rstrip()
        update_dict['InRescue'] = self.in_rescue_var.get()
        if sql_type == "edit":
            update_dict['ID'] = self.id_label.cget('text')
            sql_query = """UPDATE Animal
                       SET Name = :Name,
                       Chip_Num = :Chip,
                       Date_Of_Birth = :Dob,
                       DOB_Known = :DobKnown,
                       Sex = :Sex,
                       Colour = :Colour,
                       Hair_Type = :Hair,
                       Notes = :Notes,
                       In_Rescue = :InRescue
                       WHERE ID = :ID"""

            AdvDbQuery(self.conn, sql_query, update_dict, returnlist=False)
        elif sql_type == "save":
            next_id_qry = """SELECT ID FROM Animal ORDER BY ID DESC LIMIT 1"""
            next_id_returns = BasicDbQuery(self.conn, next_id_qry)
            next_id = int(next_id_returns[1][0][0]) + 1
            update_dict['ID'] = next_id
            sql_query = """INSERT INTO Animal (
                        Name,
                        Chip_Num,
                        Date_Of_Birth,
                        DOB_Known,
                        Sex,
                        Colour,
                        Hair_Type,
                        Notes,
                        In_Rescue)
                        VALUES (
                        :Name,
                        :Chip,
                        :Dob,
                        :DobKnown,
                        :Sex,
                        :Colour,
                        :Hair,
                        :Notes,
                        :InRescue
                        )"""
            AdvDbQuery(self.conn, sql_query, update_dict, returnlist=False)

        self.close_window()
        self.main_win.refresh_main_tree()

    def close_window(self):
        self.master.destroy()

    def _show_hide_date(self, event):
        option = self.dob_known_1.get()
        if option in ("Yes", "Roughly"):
            self.dob_cal.pack(side="top", anchor="n", fill="x")
        else:
            self.dob_cal.pack_forget()

    def _populate_data(self, conn, id):
        populate_query = "SELECT * FROM Populate_Animal_Data WHERE ID = :ID"
        populate_dict = {'ID': id}
        results = AdvDbQuery(conn, populate_query, populate_dict)

        # Update widgets
        # ID
        id_text = results[1][0][results[0].index('ID')]
        self.id_label.configure(text=id_text)

        # Name
        name_text = results[1][0][results[0].index('Name')]
        self.name_entry.insert(0, name_text)

        # Chip num
        chip_num_text = results[1][0][results[0].index('Chip_Num')]
        self.chip_num_1.insert(0, chip_num_text)

        # DOB known
        dob_known_text = results[1][0][results[0].index('DOB_Known')]
        self.dob_known_1.set(dob_known_text)
        self._show_hide_date("")

        # Date of birth
        if dob_known_text != "No":
            dob_text = results[1][0][results[0].index('Date_Of_Birth')]
            new_date = datetime.strptime(dob_text, '%Y-%m-%d')
            new_date_text = new_date.strftime('%d/%m/%Y')
            self.dob_cal.selection_set(new_date)
            self.dob_text_1.configure(text=new_date_text)

        # Sex
        sex_text = results[1][0][results[0].index('Sex')]
        self.sex_1.set(sex_text)

        # Colour
        colour_text = results[1][0][results[0].index('Colour')]
        self.colour_1.insert(0, colour_text)

        # Hair type
        hair_type_text = results[1][0][results[0].index('Hair_Type')]
        self.hair_type_1.set(hair_type_text)

        # Notes
        notes_text = results[1][0][results[0].index('Notes')]
        self.note_text.insert('end', notes_text)

        # In rescue
        in_rescue_value = results[1][0][results[0].index('In_Rescue')]
        self.in_rescue_var.set(in_rescue_value)