Update dataframe from another class in tkinter - python

I would like to update a data frame displayed in tkinter getting the data from another class.
In my app, I have defined the frames using classes. By changing an input parameter in a class, the data frame should update in another class.
For instance, I select the multiplier in the OptionMenu within the class Commands and the column B in the data frame displayed in the class Table should be updated by this multiplier. But as I change the multiplier, the data frame does not update. I am using here Treeview to display the data frame.
As I start the app, the GUI appears like the following. The narrow stripe on the right is the empty data frame. I initialize it as empty and it remains empty even if I change the multiplier. While instead it should look like the previous screenshot.
Of course the full app is much more sophisticated, but here I simplify things for the sake of the question. Actually, the data frame contains many columns and the calculation is quite complex.
I try to pass the object through a controller method. For instance, in the class Table (which displays the data frame), I define:
class Table(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
...
get_metrics = self.controller.get_page(Commands)
self.metrics = get_metrics.metrics
Where I (wrongly) suppose that the data frame self.metrics to be displayed in this frame gets updated by calling the function get_page() via the controller object. The function get_page gets the object metrics from the class Commands and is defined in the main class sampleApp as simple as:
def get_page(self, page_class):
return self.frames[page_class]
The other class Commands contains the same method parent / controller to allow the objects to be passed among classes.
class Commands(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
self.metrics = pd.DataFrame()
In the class Commands, I initialize the data frame self.metrics as empty initially (but this is not important). Later in the class Commands, I update the data frame with the function calculate_df, which is a function that does not return anything and should remain so. Therefore, the data frame object calculated there is defined as global.
I update the data frame self.metrics in the class Commands using an OptionMenu method that calls the following two lines:
calculate_df(mult = self.mult)
self.metrics = df
Here df is global and I intentionally not define with the direct command self.metrics = calculate_df(...).
The function calculate_df creates a data frame of two columns where the column B gets multiplied. For example with a multiplier of 2 df becomes:
A B
0 0 0
1 1 2
2 2 4
3 3 6
4 4 8
I post the full code in the following.
import numpy as np
import pandas as pd
pd.set_option('display.max_columns', 20)
pd.set_option('display.width', 200)
import tkinter as tk
from tkinter import ttk
def calculate_df(mult = 1.0):
global df
columns = [np.arange(5), np.arange(5) * mult]
df = pd.DataFrame(data=np.array(columns).T, columns=['A', 'B'])
class sampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "sampleApp")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
frame = Commands(parent=container, controller=self)
self.frames[Commands] = frame
frame.grid(row=0, column=0)
# frame.pack()
self.show_frame(Commands)
frame = Table(parent=container, controller=self)
self.frames[Table] = frame
frame.grid(row=0, column=1)
# frame.pack()
self.show_frame(Table)
def show_frame(self, frame_name):
frame = self.frames[frame_name]
frame.tkraise()
def get_page(self, page_class):
return self.frames[page_class]
class Table(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
table_frame = tk.Frame(self, bd=1, relief=tk.RIDGE)
table_frame.pack(fill='x')
get_metrics = self.controller.get_page(Commands)
self.metrics = get_metrics.metrics
# columns = [np.arange(5), np.arange(5) * 2]
# df = pd.DataFrame(data=np.array(columns).T, columns=['A', 'B'])
# self.metrics = df
tv1 = ttk.Treeview(table_frame)
tv1.pack()
def display_metrics():
tv1.delete(*tv1.get_children())
tv1["column"] = list(self.metrics.columns)
tv1["show"] = "headings"
for column in tv1["columns"]:
tv1.heading(column, text=column) # set column heading
df_rows = self.metrics.to_numpy().tolist() # convert dataframe to list
for row in df_rows:
# inserts each list into the treeview.
tv1.insert("", "end", values=row)
display_metrics()
class Commands(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
self.metrics = pd.DataFrame()
side_frame = tk.Frame(self, relief=tk.RIDGE)
side_frame.pack()
buttons_frame = tk.Frame(side_frame, bd=1, relief=tk.RIDGE)
buttons_frame.pack(fill='x')
Lab1 = tk.Label(buttons_frame, text="multiplier", anchor=tk.W)
Lab1.grid(row=1, column=0)
def set_multiplier(*args):
self.mult = float(mult_var.get())
print("multiplier", self.mult)
calculate_df(mult = self.mult)
self.metrics = df
mult_var = tk.StringVar(self)
mult_var.set('')
mult_var.trace("w", set_multiplier)
opt_mult = tk.OptionMenu(buttons_frame, mult_var, *[1, 2, 3, 4])
opt_mult.grid(row=2, column=2, columnspan=1)
if __name__ == '__main__':
app = sampleApp()
app.geometry("+35+35")
app.mainloop()

First change tv1 to instance variable self.tv1 and nested function display_metrics() to class function of Table. Also pass the required metrics to display_metrics() as an argument.
Then you can call Table.display_metrics() directly inside nested function set_multiplier() inside Commands class:
...
class Table(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
table_frame = tk.Frame(self, bd=1, relief=tk.RIDGE)
table_frame.pack(fill='x')
# changed tv1 to instance variable self.tv1
self.tv1 = ttk.Treeview(table_frame, show="headings")
self.tv1.pack()
# change display_metrics() to class function with added argument metrics
def display_metrics(self, metrics):
self.tv1.delete(*self.tv1.get_children())
self.tv1["column"] = list(metrics.columns)
for column in self.tv1["columns"]:
self.tv1.heading(column, text=column) # set column heading
df_rows = metrics.to_numpy().tolist() # convert dataframe to list
for row in df_rows:
# inserts each list into the treeview.
self.tv1.insert("", "end", values=row)
class Commands(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.parent = parent
self.controller = controller # save the reference to the controller in each class
self.metrics = pd.DataFrame()
side_frame = tk.Frame(self, relief=tk.RIDGE)
side_frame.pack()
buttons_frame = tk.Frame(side_frame, bd=1, relief=tk.RIDGE)
buttons_frame.pack(fill='x')
Lab1 = tk.Label(buttons_frame, text="multiplier", anchor=tk.W)
Lab1.grid(row=1, column=0)
def set_multiplier(*args):
self.mult = float(mult_var.get())
print("multiplier", self.mult)
calculate_df(mult = self.mult)
self.metrics = df
# update table
self.controller.get_page(Table).display_metrics(self.metrics)
mult_var = tk.StringVar(self)
mult_var.set('')
mult_var.trace("w", set_multiplier)
opt_mult = tk.OptionMenu(buttons_frame, mult_var, *[1, 2, 3, 4])
opt_mult.grid(row=2, column=2, columnspan=1)
...
Note that it is better to change nested function set_multiplier() to class method as well.

You can create a static method to achieve this.
You will have to read a bit about the topic.
But in short. You define a static method in Table class and then you can call that function in Commands class without initializing an instance of Table class. The static method can be called using Table.my_method(value).

Related

Python - accessing a local variable from another class

I have tried to condense the code down as much as possible to make it clear what I am asking...
I have a variable called chosen_name, determined in a class called booking_frame, that I would like to access in the calendar_frame class.
Therefore, it would be obvious for calendar_frame to inherit the attributes of booking_frame - however, I believe (I'm probably completely wrong lol) that calendar_frame has to inherit the characteristics of Frame so that the whole program functions correctly.
The reason that calendar_frame is a completely separate class is so that it can appear as a different frame.
Extremely grateful for any help given :)
# import tkinter modules
from tkinter import *
from tkinter import ttk
import tkinter.font as tkFont
from PIL import ImageTk, Image
from tkcalendar import *
# define self
class tkinterApp(Tk):
def __init__(self,*args, **kwargs):
Tk.__init__(self, *args, **kwargs)
# creating a container
container = Frame(self)
container.pack(side = "top", fill = "both", expand = True)
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
# initialising frames to an empty array
self.frames = {}
menu_bar = Menu(container)
main_menu = Menu(menu_bar)
menu_bar.add_cascade(label="Main Menu", menu=main_menu)
main_menu.add_command(label="Welcome page", command=lambda: self.show_frame(welcome_frame))
main_menu.add_command(label="Book a vehicle", command=lambda: self.show_frame(booking_frame))
main_menu.add_command(label="Register as new user", command=lambda: self.show_frame(register_frame))
Tk.config(self, menu=menu_bar)
for F in (welcome_frame, booking_frame, register_frame, calendar_frame):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
self.show_frame(welcome_frame)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class welcome_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
welcome = Label(self, text="Hello, please use the menu above to navigate the interface")
welcome.grid(row=0, column=4, padx=10, pady=10)
class register_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
register_label = Label(self, text="New user - enter your details below to use the Collyer's car park.")
register_label.grid()
class booking_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
chosen_name = "Steve"
class calendar_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
print(booking_frame.chosen_name)
app = tkinterApp()
app.geometry("1000x800")
app.title("Collyer's Car Park")
app.mainloop()
First you need to change local variable chosen_name to instance variable self.chosen_name inside booking_frame class, otherwise it cannot be accessed outside the class:
class booking_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
self.chosen_name = "Steve" # changed to instance variable
Then you can access it via controller.frames[booking_frame].chosen_name inside calendar_frame class:
class calendar_frame(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
print(controller.frames[booking_frame].chosen_name)
Inheritance is to model relationships of objects which behave the same ("IS A" relationship). It is not meant to share data between objects.
A possible solution to your problem is to use a third object, that would be shared
between booking_frame and calendar_frame.
This object can be a Python dictionary for example ; you can pass it to all your
"frame" objects, or you can maybe decide to have it global (not very academic, for sure, but quick and dirty):
GLOBAL_STATE = {}
class booking_frame(Frame):
...
GLOBAL_STATE["chosen_name"] = "Steve"
class calendar_frame(Frame):
...
print(GLOBAL_STATE.get("chosen_name"))
I hope you can see now how you can refactor your code to share data between those objects.

Python Tkinter, problem with creating unique ListBox on new pages

In tkinter I have step up multiple pages, each page should have a unique Listbox that will be populated with unique information.
My problem is the 'listbox' shows the information from my initial page on the other pages. Even if I completely remove the List box from the other pages, the 'Listbox` from my first page still shows up.
This is basically the first time I have used classes with anything, so I am not sure why this isn't working. This is all basically copied form YouTube how to's, and I am trying to bend it to what I need.
class Uploader(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs) #sets up tk window stuff
container = tk.Frame(self)
container.grid(row = 0, column = 0)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Gr7, Gr8, Gr9): #put new pages on this
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column = 0, sticky = "nsew")
self.show_frame(Gr7)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class Gr7(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self, parent)
lb = tk.Listbox(width=30, height=15)
lb.insert('end', *homelist)
lb.grid(row = 1, column = 0)
class Gr8(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self, parent)
lb1 = tk.Listbox(width=30, height=15)
lb1.insert('end', *homelist1)
lb1.grid(row = 1, column = 0)
class Gr9(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self, parent)
lb2 = tk.Listbox(width=30, height=15)
lb2.insert('end', *homelist2)
lb2.grid(row = 1, column = 0)
You are not specifying which widget should contain the listbox, so all of your listboxes are given the root window as its master. Because you are putting them all in the same row and column, you only see one listbox.
To fix this -- and as a good general rule of thumb -- you should always explicitly provide the master when creating widgets:
lb = tk.Listbox(self, width=30, height=15)

Failed to access the variable from another class in Tkinter

I am trying to develop a Tkinter GUI which contains two pages, the first one to input stock name (counter_selection) and the second one to plot stock price data. However, when I tried to use the data input from the first class using controller.get_page function it does not return the value input by Entry. The code is as below:
class Application(Tk.Tk):
'''A GUI Application for FCN Demo'''
def __init__(self):
'''Initialization of frame'''
Tk.Tk.__init__(self)
container = Tk.Frame(self)
container.pack(side='top', fill = 'both', expand = True)
container.grid_rowconfigure(0,weight = 1)
container.grid_columnconfigure(0,weight = 1)
self.frames = {}
for F in (StartPage, counter_selection, plot_counter):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row= 0, column = 0, sticky = "nsew")
self.show_frame(StartPage)
def get_page(self,classname):
'''Returns an instace of page given it's class name as a string'''
for page in self.frames.values():
if str(page.__class__.__name__) == classname:
return page
return None
def show_frame(self,cont):
frame = self.frames[cont]
frame.tkraise()
class counter_selection(Tk.Frame):
def __init__(self, parent, controller):
'''This is to create the widgets to input stock'''
Tk.Frame.__init__(self,parent)
self.controller = controller
label1 = Tk.Label(self, text = "Please Enter 3 counter names")
label1.pack(padx = 10, pady = 10)
self.entry1 = Tk.Entry(self)
self.entry1.pack()
self.entry2 = Tk.Entry(self)
self.entry2.pack()
self.entry3 = Tk.Entry(self)
self.entry3.pack()
button1 = Tk.Button (self, text = 'Confirm', command = lambda: controller.show_frame(plot_counter))
button1.pack()
class plot_counter(Tk.Frame):
'''This is to plot the graph of three selected counters'''
def __init__(self,parent,controller):
Tk.Frame.__init__(self,parent)
self.controller = controller
counterPage = self.controller.get_page('counter_selection')
self.counter1 = counterPage.entry1.get()
self.counter2 = counterPage.entry2.get()
self.counter3 = counterPage.entry3.get()
label1 = Tk.Label(self, text = self.counter11)
label1.pack()
The label1 does not show anything on the Frame, suggesting that it seems failed to get the value from the class. What's my mistake?
(PS: I didn't put the StartPage in since it is irrelevant for the question)
Why is Tkinter Entry's get function returning nothing?
TL;DR: your call to entry1.get() is done only once while instancing the plot_counter object, and never called again. Try putting it in a function to be called when displaying the Frame.

Dynamically instantiate pages Tkinter

I'm building a GUI with code that originally came from another stack exchange answer. I've modified it since I want to pass variables to following pages and have them display the values. As a way to do this, rather than display on a button event, I am trying to create the page with the show() method:
import Tkinter as tk
#import vpnRename12 as Rename
#import vpnRename_pullconfig as pullConfig
"""
Create multiple pages to go through in the same frame. Use lift() to bring
the desired page into view and stack them on top of one another. Define
page-specific methods in each page.
"""
class vpnRenameProgram(tk.Tk):
"""
Create a page class that will allow you to lift to front the applicable
page with the proper functions to keep the script running.
"""
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
# Create an empty dictionary to contain all of the page names
self.frames = {}
self.show("MainView")
# Instantiate the next page on call, rather than at start to allow
flexibility
def instantiate_page(self, cls):
"""
Since all of the pages are defined in the same scope/namespace, we
can use
the globals()[] dict to find and instantiate the pages dynamically
with the show() method.
cls is the class argument we are doing a lookup on in the global()
dict.
"""
try:
newframe = globals()[cls](container,self)
page_name = newframe.__name__
except:
print("\nError defining inline class %s"%cls)#("Class %s is not defined" %cls)
newframe = None
page_name=globals()[cls].__name__
return newframe, page_name
# Create lift function to bring desired page to front of view,
#instantiate page if
# it isn't already (check frames dict)
def show(self, cls):
if cls not in self.frames.keys():
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
frame, page_name = self.instantiate_page(cls)
if frame==None:
frame = globals()[cls](parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="news")
frame = self.frames[cls]
frame.lift()
def get_page(self, classname):
"""
Return instance of page when it's class name is passed in as string
"""
for page in self.frames.values():
if str(page.__class__.__name__) == classname:
return page
return None
class MainView(tk.Frame):
def __init__(self,parent, controller,**kwargs):
tk.Frame.__init__(self,parent)
self.controller = controller
self.edit_directory="edit_dir"
self.complete_directory ="comp_dir"
TitleLabel = tk.Label(self, text="VPN Script Editor")
TitleLabel.pack({"side":"top"})
EditLabel = tk.Label(self, text="Edit File Directory:
%s"%self.edit_directory)
EditLabel.pack()
CompLabel = tk.Label(self, text="Completed File Directory:
%s"%self.complete_directory)
CompLabel.pack()
Next = tk.Button(self, text="Next", command=lambda:
controller.show("listVPN"))
Next.pack()
class listVPN(tk.Frame):
"""
This is the second page, it contains a text box where you will list the
names of the vpn's that you want to edit. It will also display the
directories
obtained by the pullconfig script.
"""
def read_list(self):
vpn_list=str(self.var_vpn_list.get()).upper()
return vpn_list
def __init__(self, parent, controller, **kwargs):
self.controller = controller
tk.Frame.__init__(self, parent)
self.var_vpn_list = tk.StringVar()
label=tk.Label(self, text="Please list the VPNs desired to edit")
label.pack()
#Create text box to submit a list of vpns back to the main program
vpnLabel = tk.Label(self, text="VPN Names").pack()
self.TextBox = tk.Entry(self, textvariable=self.var_vpn_list)
self.TextBox.pack()
vpnListSubmit = tk.Button(self, text="Enter", command= lambda:
self.read_list() and self.controller.show("pickFiles"))
vpnListSubmit.pack()
class pickFiles(tk.Frame):
"""
Second page that allows you to select your desired files from the
edit directory specified in the config file. Check all desired files,
list will be returned to the program.
"""
def get_vpn_list(self):
list = self.controller.get_page("listVPN").var_vpn_list.get()
self.vpn_list = str(list).upper()
self.vpn_label.configure(text="VPN List: %s"%self.vpn_list)
return self.vpn_list
def __init__(self, parent, controller,**kwargs):
# Inherits from the tk.Frame class
tk.Frame.__init__(self, parent)
self.controller = controller
self.vpn_list = tk.StringVar()
list = self.controller.get_page("listVPN").var_vpn_list.get()
self.vpn_list = str(list).upper()
show_vpn = tk.Button(self, text="Show vpnlist", command =
self.get_vpn_list)
show_vpn.pack()
self.vpn_label = tk.Label(self, text="VPN List: %s" %self.vpn_list)
self.vpn_label.pack()
# todo: get external module function to run with variable input
#file_list = Rename.searchFile(vpnlist)
# Execute program on calling the parent class
if __name__=="__main__":
app = vpnRenameProgram()
app.mainloop()
EDIT:
Above is my whole code with custom scripts I've imported commented out. My main question is about layout. I want the frames to stack on top of one another, but they are not. Why is it doing this and what would get me on track to getting the layout I want?
The main problem with your code is that you're creating multiple containers. The code that served as a base for your program was specifically designed to have a single container with multiple frames within the container.
The first step is to create the container, and save a reference so it can be used later:
class vpnRenameProgram(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.container = tk.Frame(self)
self.container.pack(side="top", fill="both", expand=True)
self.container.grid_rowconfigure(0, weight=1)
self.container.grid_columnconfigure(0, weight=1)
self.frames = {}
self.show_frame("MainView")
I'm also going to recommend that you pass the actual class instead of a class name. This way you don't have to dig into globals() to try to find the right class based on the name.
Change the last line in the above to look like this:
self.show_frame(MainView)
You will also need to change get_page, but it's now a simple lookup:
def get_page(self, page_class):
return self.frames.get(page_class, None)
The final step is to redefine show to create the frame on demand. You've created a method called instantiate_page, but I see no real reason not to put it all in a single function since it's only a couple extra lines of code:
def show(self, page_class):
if page_class in self.frames:
frame = self.frames[page_class]
else
frame = page_class(parent=self.container, controller=self)
frame.grid(row=0, column=0, sticky="nsew")
self.frames[page_class] = frame
frame.tkraise()
That's all there is to it. You just need to remember to pass the class rather than the name of the class when calling show or get_page (eg: controller.show(listVPN), controller.get_page(pickFiles)`, etc)

3 ValueError: dictionary update sequence element #0 has length 3; 2 is required 1

I am using tkinter and trying to create a library of frames instead of having my program open new windows every time. I have begun creating a welcome page and I am trying to display what I have created only for it to give me this error message. "ValueError: dictionary update sequence element #0 has length 1; 2 is required"
Here is my code:
#!/usr/bin/python
from tkinter import *
import tkinter as tk
Large_Font = ("Verdana", 18)
class ATM(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side = "top", fill ="both", expand =True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for i in (WelcomePage, Checking):
frame = i(container, self)
self.frames[i] = frame
frame.grid(row= 0, column = 0, sticky= "nsew")
self.show_frame(WelcomePage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class WelcomePage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, "Welcome to the ATM Simulator", font = Large_Font)
label.pack(pady=100, padx=100)
checkButton = Button(self, text = "Checking Account",
command = lambda: controller.show_frame(Checking))
checkButton.pack()
class Checking(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, controller)
self.controller = controller
label = tk.Label(self, "Welcome to the ATM Simulator", font = Large_Font)
label.pack(pady=100, padx=100)
homeButton = Button(self, text = "Back to Home Page",
command = lambda: controller.show_frame(WelcomePage))
homeButton.pack()
app = ATM()
app.mainloop()
The error message is occurring because I state that
frame = i(container, self)
but when I create the class I state
class WelcomePage(tk.Frame):
The dictionary element in my WelcomePage class only has 1 parameter but I need two. I tried putting self as the second parameter but that did not work. This worked in Python 3.4 but now that I am using Python 3.5 it gives me this error. How would I fix this?
class Checking(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, controller)
I don't think Frame's initializer can accept that many arguments unless controller is a dictionary. Try:
class Checking(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
You should also use the text named argument to specify the text for your labels.
label = tk.Label(self, text="Welcome to the ATM Simulator", font = Large_Font)

Categories