Python Forum
[Tkinter] How might I use classes in my code
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] How might I use classes in my code
#1
After learning a little bit of Python I wrote a short program, then used tkinter to make a simple gui but I know if I'm going to get anywhere with Python I need to learn classes and OOP.

I understand the basics but can't see how I might be able to apply classes to my code. It may be that my code is so simple classes can't be used, I certainly doubt it's necessary.

I did try to add a class to just the "select_day" function but immediately got stuck because I have the event value (I think it's called a value :|).

I know it's probably not worth using classes in this code but is it possible and how might you go about it?. Oh, and while I'm at it... is the way I've layout/arranged the code in keeping with the norm? I tried to put all the functions at the top then the gui but didn't know where to put the dictionaries.

Thank you for any help!
# Day of the week calculator
# Using Zeller's congruence

from tkinter import *
from tkinter.ttk import *

##### Create root window, a frame in the window and a grid to place widegets #####
root = Tk()
root.title("Day of the Week Calculator")
root.geometry("800x300")
frame = Frame(root)
frame.grid()

##### Dictionaries #####
day_key={   0:"Saturday",
            1:"Sunday",
            2:"Monday",
            3:"Tuesday",
            4:"Wednesday",
            5:"Thursday",
            6:"Friday"}

month_value={   "January":13,
                "February":14,
                "March":3,
                "April":4,
                "May":5,
                "June":6,
                "July":7,
                "August":8,
                "September":9,
                "October":10,
                "November:":11,
                "December":12}

##### Get date (day,month,year) and perform calculation #####
def select_day(event):
    global q
    q = int(combo_day.get())

def select_month(event):
    global m
    m = int(month_value[combo_month.get()])

def select_year(event):
    global year, year_input, k, j, leap
    year_input = int(entry_year.get())

    if m in [13,14]:
        year=int(year_input-1)
    else:
        year=int(year_input)
    
    if (year_input%4) == 0:
        if (year_input%100) == 0:
            if (year_input%400) == 0:
                leap = True
            else: leap = False
        else:
            leap = True
    else:
        leap = False   
 
    k = int(year%100)
    j = int(year//100)

def calculation():
    if m in (4,6,9,11) and q not in range(1,31):
        output_text=("This date is invalid. You can't have", q, "days in", combo_month.get())
        invalid_date = Label(frame, text=output_text).grid(row=3, column=2)
    elif leap == False and m == 14 and q not in range(1,29):
        invalid_date = Label(frame, text="This date is invalid. You can only have up to 28 days in February").grid(row=3, column=2)
    elif leap == True and m == 14 and q not in range(1,30):
        invalid_date = Label(frame, text="This date is invalid. Even though it's a leap year you can only have up to 29 days in February").grid(row=3, column=2)            
    elif year_input == 1752 and m == 9 and q in range(3,14):
        lbl_invalid_date_jul_greg = Label(frame, text="This date is invalid. When Britain, Ireland and the colonies switched from the Julian calendar to the Gregorian calendar they went to bed on the 3rd September 1752 and woke up on the 14th September!").grid(row=3, column=2)
    else:
        if year_input <=1752 and m >= 9 and q <3:
            day = day_key[(q + 13*(m+1)//5 + k + k//4 + 5 - j) %7]
            print_result = Label(frame, text=day).grid(row=4, column=0)
        else: 
            day = day_key[(q + 13*(m+1)//5 + k + k//4 + j//4 - 2*j) %7]
            print_result = Label(frame, text=day).grid(row=4, column=0)

##### GUI #####
lbl_day = Label(frame, text="Day")
lbl_day.grid(row=1, column=0, padx=20)

lbl_month = Label(frame, text="Month")
lbl_month.grid(row=1, column=1, padx=20)

lbl_year = Label(frame, text="Year")
lbl_year.grid(row=1, column=2, padx=20)

combo_day = Combobox(frame)
combo_day['values'] = list (range(1,32))
combo_day.set("Choose a day")
combo_day.grid(row=2, column=0)
combo_day.bind("<<ComboboxSelected>>", select_day)

combo_month = Combobox(frame)
combo_month.grid(row=2, column=1)
combo_month['values'] = list (month_value.keys())
combo_month.set("Choose a month")
combo_month.bind("<<ComboboxSelected>>", select_month)

entry_year = Entry(frame)
entry_year.grid(row=2, column=2)
entry_year.insert(0,"Choose a year") 
entry_year.bind("<KeyRelease>", select_year) 

##### Provide result #####
but_process_data = Button(frame, text="Process data", command=calculation).grid(row=2, column=3, padx=20)

root.mainloop()
Reply
#2
Here is an example of altering your code into classes, I have left the logic/naming etc as it was, the original code is in the comments.
# Day of the week calculator
# Using Zeller's congruence

# from tkinter import *
import tkinter as tk
# from tkinter.ttk import *
from tkinter import ttk

##### Dictionaries #####
day_key = {0: "Saturday",
              1: "Sunday",
              2: "Monday",
              3: "Tuesday",
              4: "Wednesday",
              5: "Thursday",
              6: "Friday"}

month_value = {"January": 13,
               "February": 14,
               "March": 3,
               "April": 4,
               "May": 5,
               "June": 6,
               "July": 7,
               "August": 8,
               "September": 9,
               "October": 10,
               "November:": 11,
               "December": 12}

##### Create root window, a frame in the window and a grid to place widegets #####
class TkApp(tk.Tk): # root = tk.Tk()
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.title("Day of the Week Calculator") # root.title("Day of the Week Calculator")
        self.geometry("800x300") # root.geometry("800x300")

class MainFrame(tk.Frame): # frame = tk.Frame(root)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.q = None
        self.m = None
        self.year = None
        self.year_input = None
        self.k = None
        self.j = None
        self.leap = None
        self.grid() # frame.grid()

# ##### GUI #####
        lbl_day = tk.Label(self, text="Day") # lbl_day = tk.Label(frame, text="Day")
        lbl_day.grid(row=1, column=0, padx=20)

        lbl_month = tk.Label(self, text="Month") # lbl_month = tk.Label(frame, text="Month")
        lbl_month.grid(row=1, column=1, padx=20)

        lbl_year = tk.Label(self, text="Year") # lbl_year = tk.Label(frame, text="Year")
        lbl_year.grid(row=1, column=2, padx=20)

        self.combo_day = ttk.Combobox(self) # combo_day = ttk.Combobox(frame)
        self.combo_day['values'] = list(range(1, 32)) # combo_day['values'] = list(range(1, 32))
        self.combo_day.set("Choose a day") # combo_day.set("Choose a day")
        self.combo_day.grid(row=2, column=0) # combo_day.grid(row=2, column=0)
        self.combo_day.bind("<<ComboboxSelected>>", self.select_day) # combo_day.bind("<<ComboboxSelected>>", select_day)

        self.combo_month = ttk.Combobox(self) # combo_month = ttk.Combobox(frame)
        self.combo_month.grid(row=2, column=1) # combo_month.grid(row=2, column=1)
        self.combo_month['values'] = list(month_value.keys()) # combo_month['values'] = list(month_value.keys())
        self.combo_month.set("Choose a month") # combo_month.set("Choose a month")
        self.combo_month.bind("<<ComboboxSelected>>", self.select_month) # combo_month.bind("<<ComboboxSelected>>", select_month)

        self.entry_year = tk.Entry(self) # entry_year = tk.Entry(frame)
        self.entry_year.grid(row=2, column=2) # entry_year.grid(row=2, column=2)
        self.entry_year.insert(0, "Choose a year") # entry_year.insert(0, "Choose a year")
        self.entry_year.bind("<KeyRelease>", self.select_year) # entry_year.bind("<KeyRelease>", select_year)

        self.invalid_date = tk.Label(self, text='')
        self.invalid_date.grid(row=3, column=2)
        self.print_result = tk.Label(self, text='')
        self.print_result.grid(row=4, column=0)

# ##### Provide result #####
        tk.Button(self, text="Process data", command=self.calculation).grid(row=2, column=3, padx=20) # but_process_data = tk.Button(frame, text="Process data", command=calculation).grid(row=2, column=3, padx=20)



##### Get date (day,month,year) and perform calculation #####

    def select_day(self, event): # def select_day(event):
        # global q
        self.q = int(self.combo_day.get()) # q = int(combo_day.get())


    def select_month(self, event): # def select_month(event):
        # global m
        self.m = int(month_value[self.combo_month.get()]) # m = int(month_value[combo_month.get()])


    def select_year(self, event): # def select_year(event):
        # global year, year_input, k, j, leap
        self.year_input = int(self.entry_year.get()) # year_input = int(entry_year.get())

        if self.m in [13, 14]: # if m in [13, 14]:
            self.year = int(self.year_input-1) # year = int(year_input-1)
        else:
            self.year = int(self.year_input) # year = int(year_input)

        if (self.year_input % 4) == 0: # if (year_input % 4) == 0:
            if (self.year_input % 100) == 0: # if (year_input % 100) == 0:
                if (self.year_input % 400) == 0: # if (year_input % 400) == 0:
                    self.leap = True # leap = True
                else:
                    self.leap = False # leap = False
            else:
                self.leap = True # leap = True
        else:
            self.leap = False # leap = False

        self.k = int(self.year % 100) # k = int(year % 100)
        self.j = int(self.year//100) # j = int(year//100)


    def calculation(self): # def calculation():
        if self.m in (4, 6, 9, 11) and self.q not in range(1, 31): # if m in (4, 6, 9, 11) and q not in range(1, 31):
            output_text = f"This date is invalid. You can't have {self.q} days in {self.combo_month.get()}" # output_text = ("This date is invalid. You can't have", q, "days in", combo_month.get())
            self.invalid_date['text'] = output_text # invalid_date = tk.Label(frame, text=output_text).grid(row=3, column=2)
        elif self.leap == False and self.m == 14 and self.q not in range(1, 29): # elif leap == False and m == 14 and q not in range(1, 29):
            self.invalid_date['text'] = "This date is invalid. You can only have up to 28 days in February" # invalid_date = tk.Label(frame, text="This date is invalid. You can only have up to 28 days in February").grid(row=3, column=2)
        elif self.leap == True and self.m == 14 and self.q not in range(1, 30): # elif leap == True and m == 14 and q not in range(1, 30):
            self.invalid_date['text'] = "This date is invalid. Even though it's a leap year you can only have up to 29 days in February" # invalid_date = tk.Label(frame, text="This date is invalid. Even though it's a leap year you can only have up to 29 days in February").grid(row=3, column=2)
        elif self.year_input == 1752 and self.m == 9 and self.q in range(3, 14): # elif year_input == 1752 and m == 9 and q in range(3, 14):
            self.invalid_date['text'] = "This date is invalid. When Britain, Ireland and the colonies switched from the Julian calendar to the Gregorian calendar they went to bed on the 3rd September 1752 and woke up on the 14th September!" # lbl_invalid_date_jul_greg = tk.Label(frame, text="This date is invalid. When Britain, Ireland and the colonies switched from the Julian calendar to the Gregorian calendar they went to bed on the 3rd September 1752 and woke up on the 14th September!").grid(row=3, column=2)
        else:
            if self.year_input <= 1752 and self.m >= 9 and self.q < 3: # if year_input <= 1752 and m >= 9 and q < 3:
                day = day_key[(self.q + 13*(self.m+1)//5 + self.k + self.k//4 + 5 - self.j) % 7]
                self.print_result['text'] = day # print_result = tk.Label(frame, text=day).grid(row=4, column=0)
            else:
                day = day_key[(self.q + 13*(self.m+1)//5 + self.k + self.k//4 + self.j//4 - 2*self.j) % 7] # day = day_key[(q + 13*(m+1)//5 + k + k//4 + j//4 - 2*j) % 7]
                self.print_result['text'] = day # print_result = tk.Label(frame, text=day).grid(row=4, column=0)


if __name__ == '__main__':
    tk_app = TkApp()
    MainFrame(tk_app)
    tk_app.mainloop() # root.mainloop()
Reply
#3
Wow... thank you!.

It's going to take me a little while to digest but it's a great help. I would never have managed to piece this together.

Big big thank you once again!
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020