Python - accessing a local variable from another class - python

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.

Related

Update dataframe from another class in tkinter

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).

Tkinter have stacking frames with list and pages in different modules

I have code below originally taken from the link here i have read all documentation in there but i feel im overlooking something, i have pages in separate modules as well as a separate module with a Add class for adding pages to the window.
The idea is to later be able to drop a module in a sub folder with a Pagexxx object within it and call the add page class to allow Tkinter to display it but i cannot seem to get the frames to stack.
Nav.py
import tkinter as tk
from Page import PageList
import Mypages
class Windowhandler(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)
PageList("Page1", container, self, Mypages.PageOne)
PageList("Page2", container, self, Mypages.PageTwo)
self.show_frame("Page1")
def show_frame(self, cont):
frameref = PageList.frames[cont]
print(frameref)
frameref.tkraise()
app = Windowhandler()
app.mainloop()
Page.py
class PageList():
frames = {}
def __init__(self, name, parent, cont, ref):
self.frames[name] = ref(parent=parent, controller=cont)
Mypages.py
import tkinter as tk
class PageOne(tk.Frame):
def __init__(self, parent, controller):
this = tk.Frame.__init__(self, parent)
label = tk.Label(this, text="Welcome to Page 1")
label.pack(pady=10, padx=10)
button1 = tk.Button(this, text="Back to Home",
command=lambda: controller.show_frame("Page2"))
button1.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
this = tk.Frame.__init__(self, parent)
label = tk.Label(this, text="Welcome to Page 2")
label.pack(pady=10, padx=10)
button1 = tk.Button(this, text="Back to Home",
command=lambda: controller.show_frame("Page1"))
button1.pack()
Before asking for help from others, the first step is to validate your assumptions. You're assuming that tk.Frame.__init__(self, parent) returns something useful, but you never validated that assumption by checking to see if it is what you think it is.
The first problem is illustrated by two lines, which are essentially the same in both pages:
this = tk.Frame.__init__(self, parent)
label = tk.Label(this, text="Welcome to Page 1")
I'm guessing you were assuming that this would be set to the instance of the Frame. However, the __init__ function returns None so this is set to None. When None is passed as the parent of a widget, that widget becomes a child of the root window.
The solution is to not use this. Use self:
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Welcome to Page 2")
The second problem is that you never add the page to the container with grid, pack, or place, so they will never be visible.
You need to change Add to actually add the page to the container:
def Add(name, parent, cont, ref):
PageList.frames[name] = ref(parent=parent, controller=cont)
PageList.frames[name].grid(row=0, column=0, sticky="nsew")

How can I integrate my classes in a final class?

In a different question about the structure of Python code one solution was proposed:
The question is here to be found: Best way to structure a tkinter application
class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.statusbar = Statusbar(self, ...)
self.toolbar = Toolbar(self, ...)
self.navbar = Navbar(self, ...)
self.main = Main(self, ...)
self.statusbar.pack(side="bottom", fill="x")
self.toolbar.pack(side="top", fill="x")
self.navbar.pack(side="left", fill="y")
self.main.pack(side="right", fill="both", expand=True)
I like the solution and tried to replicate it on a tiny scale before applying it to my code. Can somebody please help me what arguments, parameters are missing to set up the application?
See below my code:
import tkinter as tk
class Main(tk.Frame):
def __init__(self, master):
central = tk.Frame(master)
central.pack(side="top", fill="both")
class SubMain(tk.Frame):
def __init__(self,master):
lowercentral = tk.Frame(master)
lowercentral.pack(side="top", fill="both")
class MainApplication(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.central = Main(self)
self.lowercentral = SubMain(self)
self.central.pack(side="top", fill="both")
self.lowercentral.pack(side="top", fill="both")
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both")
root.mainloop()
Few words to my code. I expect the code to basically just open an empty, white window.
Class Main and SubMain should create two frames. MainApplication should integrate both classes and effectively act as the center of all classes.
However, I receive the error message:
AttributeError: 'Main' object has no attribute 'tk'
I assume, as in my example I am missing parameters in the init function of MainApplication but my variations did not yield any success.
Can somebody help me with this?
First of all when you instantiate the Main and SubMain classes you need to pass the parent and not the MainApplication instance (self).
Then you don't need to call the pack method on the classes, as both the Main and SubMain classes already pack their frame:
import tkinter as tk
class Main(tk.Frame):
def __init__(self, master):
central = tk.Frame(master)
central.pack(side="top", fill="both")
class SubMain(tk.Frame):
def __init__(self,master):
lowercentral = tk.Frame(master)
lowercentral.pack(side="top", fill="both")
class MainApplication(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.central = Main(parent)
self.lowercentral = SubMain(parent)
#self.central.pack(side="top", fill="both")
#self.lowercentral.pack(side="top", fill="both")
root = tk.Tk()
MainApplication(root)#.pack(side="top", fill="both")
root.mainloop()
You could try this in init function:
super().__init__(master)
I use it and it worked.Hope it valid.
Make sure to call super().__init__() in all of your __init__ functions. They are missing in Main and SubMain.

Tkinter Class structure (class per frame) issue with duplicating widgets

Ive been trying out OOP for use with Tkinter - Im getting there (I think) slowly...
I wanted to build a structure where each frame is handled by its own class, including all of its widgets and functions. Perhaps I am coming from the wrong angle but that is what makes most logical sense to me. - Feel free to tell me if you agree / disagree!
I know why the problem is happening - when im calling each class my __init__ runs everytime and builds the relevant widgets regardless of whether they are already present in the frame. However, the only way I can think of getting round this would be to build each frame in the __init__ of my primary class GUI_Start. - Although this seems like a messy and un-organised soloution to the problem.
Is there a way I can achieve a structure where each class takes care of its own functions and widgets but doesn't build the frame each time?
See below for minimal example of the issue:
from Tkinter import *
class GUI_Start:
def __init__(self, master):
self.master = master
self.master.geometry('300x300')
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.win_colour = '#D2B48C'
self.frames = {}
for window in ['win1', 'win2']:
frame = Frame(self.master, bg=self.win_colour, bd=10, relief=GROOVE)
frame.grid(row=0, column=0, sticky='news')
setattr(self, window, frame)
self.frames[window] = frame
Page_1(self.frames)
def Next_Page(self, frames, controller):
controller(frames)
class Page_1(GUI_Start):
def __init__(self, master):
self.master = master
self.master['win1'].tkraise()
page1_label = Label(self.master['win1'], text='PAGE 1')
page1_label.pack(fill=X)
page1_button = Button(self.master['win1'], text='Visit Page 2...', command=lambda: self.Next_Page(self.master, Page_2))
page1_button.pack(fill=X, side=BOTTOM)
class Page_2(GUI_Start):
def __init__(self, master):
self.master = master
self.master['win2'].tkraise()
page2_label = Label(self.master['win2'], text='PAGE 2')
page2_label.pack(fill=X)
page2_button = Button(self.master['win2'], text='Back to Page 1...', command=lambda: self.Next_Page(self.master, Page_1))
page2_button.pack(fill=X, side=BOTTOM)
root = Tk()
gui = GUI_Start(root)
root.mainloop()
Feel free to critique the structure as I may be trying to approach this from the wrong angle!
Any feedback would be much appreciated!
Luke
The point of using classes is to encapsulate a bunch of behavior as a single unit. An object shouldn't modify anything outside of itself. At least, not by simply creating the object -- you can have methods that can have side effects.
In my opinion, the proper way to create "pages" is to inherit from Frame. All of the widgets that belong to the "page" must have the object itself as its parent. For example:
class PageOne(tk.Frame):
def __init__(self, parent):
# use the __init__ of the superclass to create the actual frame
tk.Frame.__init__(self, parent)
# all other widgets use self (or some descendant of self)
# as their parent
self.label = tk.Label(self, ...)
self.button = tk.Button(self, ...)
...
Once done, you can treat instances of this class as if they were a single widget:
root = tk.Tk()
page1 = PageOne(root)
page1.pack(fill="both", expand=True)
You can also create a base Page class, and have your actual pages inherit from it, if all of your pages have something in common (for example, a header or footer)
class Page(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
<code common to all pages goes here>
class PageOne(Page):
def __init__(self, parent):
# initialize the parent class
Page.__init__(self, parent)
<code unique to page one goes here>
Your use of OOP is not very logical here. Your main program is in the class GUI_start. If your pages inherit from GUI_start, basically you create a whole new program with every page instance you create. You should instead inherit from Frame as Bryan Oakley has pointed our in the comments. Here is a somewhat repaired version of what you have posted. The original one by Bryan is still much better.
from Tkinter import *
class GUI_Start:
def __init__(self, master):
self.master = master
self.master.geometry('300x300')
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.win_colour = '#D2B48C'
self.current_page=0
self.pages = []
for i in range(5):
page = Page(self.master,i+1)
page.grid(row=0,column=0,sticky='nsew')
self.pages.append(page)
for i in range(2):
page = Page_diff(self.master,i+1)
page.grid(row=0,column=0,sticky='nsew')
self.pages.append(page)
self.pages[0].tkraise()
def Next_Page():
next_page_index = self.current_page+1
if next_page_index >= len(self.pages):
next_page_index = 0
print(next_page_index)
self.pages[next_page_index].tkraise()
self.current_page = next_page_index
page1_button = Button(self.master, text='Visit next Page',command = Next_Page)
page1_button.grid(row=1,column=0)
class Page(Frame):
def __init__(self,master,number):
super().__init__(master,bg='#D2B48C')
self.master = master
self.master.tkraise()
page1_label = Label(self, text='PAGE '+str(number))
page1_label.pack(fill=X,expand=True)
class Page_diff(Frame):
def __init__(self,master,number):
super().__init__(master)
self.master = master
self.master.tkraise()
page1_label = Label(self, text='I am different PAGE '+str(number))
page1_label.pack(fill=X)
root = Tk()
gui = GUI_Start(root)
root.mainloop()

Changing a tkinter frame from inside a method/function other than __init__

What im trying to do is find a way to change the Frame from a method/function other than def __init__
My main class which im using to change and manage the Frames with is:
class ShopCounter(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 (PageOne, PageTwo):
frame = i(container, self)
self.frames[i] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.showFrame(Login)
def showFrame(self, cont):
frame = self.frames[cont]
frame.tkraise()
The issue im having from here is that when i make a new window such as
class PageOne (tk.Frame):
def __init__ (self, parent, controller):
tk.Frame.__init__(self, parent)
lbl = tk.Label(self, text="Page 1")
lbl.pack()
This is also in __init__
as this calls the nextPage function (Later shown)
nextPage()
But i need to read from a CSV spread sheet to check if the person has inputted the user name and pass word (Haven't put checking code or input fields for convenience) i then find that i need to change the frame from a different function in the class PageOne
I have then met the problem of now having to define a controller in this new function s through the parenthesis of the function when it is called which is a problem because i don't know how to do that apart from just putting it as a parameter in the __init__method
Quick example:
Say the function in the class is something like this..
def nextPage (self, controller):
controller.showFrame(PageTwo)
IDLE then tells me that i the arguments for this function "controller" is missing but i don't know how I'd set that manually
I have found a fix
class PageOne (tk.Frame):
def __init__ (self, parent, controller):
tk.Frame.__init__(self, parent)
lbl = tk.Label(self, text="Page 1")
lbl.pack()
button = tk.Button(self, text="switch", command=lambda: self.launch(controller)
button.pack()
def launch (self, cont):
cont.showFrame(PageTwo)
Now I've made a function (launch) in the PageOne class which takes self and cont (the controller) as the parameters. You will then pass the controller from init into the launch function when you press the button.
Hope this helps some on. 'Cause personally I've been stumped on this one for months.
UPDATE
After months of this answer being up, i have now found a new way, rather than always passing the controller as a parameter to each function you with to use in each page class, in the initiation of the class (__ init __), you can declare a variable to the object that holds the controller, heres an example:
class PageTwo(tk.Frame):
def __init__ (self, parent, controller):
self.controller = controller
def doSomething (self):
self.controller.doSomething()
by referencing the controller you can run any class within the controller class, you can also get variable data and change it.

Categories