I am adding a scroll bar to my tkinter application. My Tkinter application already contains multiple frames which you can switch between. In order to add a scroll bar on the HomePage
, I have created a main_frame
and a canvas
, added the scroll bar to the canvas
and created another frame inside the canvas
called second_frame
. The scroll bar has appeared, however another part of my application is that on the Add_page
, the user clicks a button and an image etc. appears on the Home_page
or in this case appears in the second_frame
. My problem is, since the second_frame
etc. is defined on the HomePage
only, the Add_page
does not recognise it and I get an error message stating that name 'second_frame' is not defined
. I need to somehow ensure that these variables are recognised across all frames. Also, I have removed the StartPage
, ToDoPage
and TimetablePage
from the sample reduce the size of the code.
import calendar
import tkinter as tk
from tkinter import ttk
from tkcalendar import *
from datetime import datetime
from datetime import date
from time import strftime
from datetime import timedelta, datetime, date
x = 200
y = 250
c = 460
d = 290
e = 325
f = 355
g = 390
h = 420
i = 460
j = 490
#calendar and display in label
#window = Tk()
#window.title("StudyFriendO")
IMAGE_PATH = 'apple.png'
LARGE_FONT= ("Verdana", 24)
SMALL_FONT=("Verdana", 12)
class StudyFriendO(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title("StudyFriendO") #naming window title
self.geometry('850x830') #size of window
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
#### ADDED
self.shared_data = { # Variables shared by all pages.
'name': tk.StringVar(value=''),
'assessment': tk.StringVar(value=''),
'due_date': tk.StringVar(value='')
}
self.frames = {}
for F in (StartPage, HomePage, ToDoPage, TimetablePage, AddPage): #list of multiple frames of program
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def set_date(self, cont):
#frame: StartPage = self.frames[cont]
#frame.date_label.config(text="Today's date is " + datetime.today().strftime("%B %d, %Y")) #function to get date from
frame2: HomePage = self.frames[HomePage]
frame2.date_label.config(text= datetime.today().strftime("%B %d, %Y")) #function to get date from
def getname(self, cont): #FUNCTION WHICH GRABS NAME FROM TEXT ENTRY
frame2: HomePage = self.frames[HomePage]
#### frame2.name_label.configure(text=nameentry.get() + "'s Planner ")
frame2.name_label.configure(text=self.shared_data['name'].get() + "'s Planner ")
def step(self):
self.frames[HomePage].my_progress['value']+= 5
def display(self, cont):
frame2: HomePage = self.frames[HomePage]
#blue box
global x , y , c , d , e , f , g, h, i, j
box_image = tk.PhotoImage(file='apple.png')
frame2.panel2 = tk.Label(second_frame, image=box_image, bg='#f7f6f6')
frame2.panel2.image = box_image
frame2.panel2.place(x=x, y=y)
x=x
y = y+260
#assessment name
frame2.n = tk.Label(frame2, text="", bg="#e0f6fc", font=60)
frame2.n.place(x=c, y=d, anchor='center')
frame2.n.configure(text=self.shared_data['assessment'].get())
c=c
d=d+260
#due date
frame2.d = tk.Label(frame2, text="Due:", bg="#e0f6fc", font=SMALL_FONT)
frame2.d.place(x=c, y=e, anchor='center')
c=c
e=e+260
#cal date
frame2.c= tk.Label(frame2, text="", bg="#e0f6fc", font=SMALL_FONT)
frame2.c.place(x=c, y=f, anchor='center')
frame2.c.configure(text=self.shared_data['due_date'].get())
c=c
f=f+260
#no. of days
plum = datetime.today().strftime("%m/%d/%y")
date_format = "%m/%d/%y"
a = datetime.strptime(plum, date_format)
pear = self.shared_data['due_date'].get()
b = datetime.strptime(pear, date_format)
delta = b - a
frame2.days = tk.Label(frame2, font=LARGE_FONT, bg="#e0f6fc")
frame2.days.place(x=c, y=g, anchor='center')
c=c
g=g+260
frame2.days.config(text=delta.days)
frame2.no_of_days=tk.Label(frame2, text="DAYS",bg="#e0f6fc")
frame2.no_of_days.place(x=c, y=h, anchor='center')
c=c
h=h+260
#progress bar
frame2.my_progress = ttk.Progressbar(frame2, orient='horizontal', length=300, mode='determinate')
frame2.my_progress.place(x=c, y=i, anchor='center')
c=c
i=i+260
frame2.my_button = tk.Button(frame2, text="Progress", command=self.step)
frame2.my_button.place(x=c, y=j, anchor='center')
c=c
j=j+260
class HomePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#### creating scrollbar ####
#create a main frame
main_frame = tk.Frame(self, bg='#f7f6f6')
main_frame.pack(fill='both', expand=1)
#create a canvas
my_canvas = tk.Canvas(main_frame, bg='#f7f6f6')
my_canvas.pack(side='left', fill='both', expand=1)
#add a scroll bar to the canvas
my_scrollbar = ttk.Scrollbar(main_frame, orient='vertical', command=my_canvas.yview)
my_scrollbar.pack(side='right', fill='y')
#create another frame inside the canvas
second_frame = tk.Frame(my_canvas)
# add that new frame to a window in the canvas
my_canvas.create_window((0,0), window=second_frame, anchor="nw", width="10000")
#label = tk.Label(self, text="Home", font = LARGE_FONT)
#label.pack(pady=10,padx=10)
#height of Y
tk.Label(main_frame, text="", fg="white", bg="#99cbd8").place(anchor='w', relheight=2, width='150') #ipadx=73)
#width of x
frame = tk.Frame(main_frame, bg="#c0e3ed", height=110)
frame.place(anchor='n', relwidth=2)
#LABEL WHICH DISPLAYS NAME FROM TEXT ENTRY
#tk.Label(self, text ="Name's Planner", fg="white", bg="#c0e3ed", font = LARGE_FONT).place(relx=0.5, y=50, anchor='center')
self.name_label = tk.Label(main_frame, text="", font=("Arial Bold", 40), bg="#c0e3ed")
self.name_label.place(relx=0.55, y=55, anchor='center')
self.date_label = tk.Label(second_frame, text="", bg="#c0e3ed")
# keep placing the label at top right corner
self.date_label.place(relx=1, y=0, anchor='ne')
#pack(side='top', anchor='ne')
button1 = tk.Button(main_frame, height=2, width=10, bg="#e0f6fc", text="Home", command=lambda: controller.show_frame(HomePage)) #button to navigate page
button1.place(x=35, y=145)
button1 = tk.Button(main_frame, height=2, width=10, bg="#e0f6fc", text="To Do", command=lambda: controller.show_frame(ToDoPage)) #button to navigate page
button1.place(x=35, y=225)
#(relx=0.2, rely=0.4, anchor='center')
button1 = tk.Button(main_frame, height=2, width=10, bg="#e0f6fc", text="Timetable", command=lambda: controller.show_frame(TimetablePage)) #button to navigate page
button1.place(x=35, y=305)
photo2 = tk.PhotoImage(file='apple.png') #photo1 is a variable
#label (window, image=photo1, bg="black") .grid(row=0, column=0, sticky=E)
panel = tk.Label(main_frame, image = photo2)
panel.image = photo2
panel.place(x=35, y=400)
#your upcoming assesments title
title = tk.Label(main_frame, text="Your Upcoming Assesments", bg='#f7f6f6', font=LARGE_FONT)
title.place(x=200, y=150)
add_button = ttk.Button(main_frame, text="Add", command=lambda: controller.show_frame(AddPage))
add_button.place(relx=0.8, rely=1, anchor='se')
save_button = ttk.Button(main_frame, text="Save")
save_button.place(relx=0.9, rely=1, anchor='se')
clear_button = ttk.Button(main_frame, text="Clear")
clear_button.place(relx=1, rely=1, anchor='se')
self.configure(bg='#f7f6f6')
class AddPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
#width of x
frame = tk.Frame(self, bg="#c0e3ed", height=110)
frame.pack(fill="x")
label = tk.Label(self, text="Add Assesment", font = LARGE_FONT, bg="#c0e3ed")
label.place(relx=0.5, y=50, anchor='center')
assessment_label = tk.Label(self, text="Enter assesment name:")
assessment_label.place(relx=0.5, y=200, anchor='center')
assessment_name = tk.Entry(self, textvariable=controller.shared_data['assessment'])
assessment_name.place(relx=0.5, y=220, anchor='center')
cal2 = Calendar(self, textvariable=controller.shared_data['due_date'], background="#e0f6fc", disabledbackground="white", bordercolor="light blue", headersbackground="light blue", normalbackground="#e0f6fc", foreground="black", normalforeground='black', headersforeground='white', selectmode="day", year=2021, month=8, day=9)
cal2.place(relx=0.5, y=400, anchor='center')
due_date = ttk.Button(self, text="Submit")
due_date.place(relx=0.5, y=510, anchor='center')
add_button = ttk.Button(self, text="Add Assesment", command=lambda: controller.display(HomePage))
add_button.place(relx=0.5, y=560, anchor='center')
button1 = ttk.Button(self, text="Home", command=lambda: controller.show_frame(HomePage)) #button to navigate page
button1.pack()
app = StudyFriendO()
app.mainloop()