I created a quiz in tkinter , which goes from page to page and adding to the variable "score".
But if i want to display the final score it shows the initial value instead of the actual one.
Does somebody have a similar problem or an idea for a solution?
Thanks
import tkinter as tk
from tkinter import font as tkfont
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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,theme1page,theme2page,theme1Q1,theme1Q2,theme1Q3,\
theme1Q4,theme1Q5,theme2Q1,theme2Q2,theme2Q3,theme2Q4,theme2Q5, Results):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
We directly show the last question page for simplicity. The variable score is the one we increase while answering correctly.
class theme1Q5(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="5.Question", font=controller.title_font)
label.pack(side="top", fill="x")
Question15 = tk.Label(self, text="Which sentence is not true?")
Question15.place(x=0, y = 30)
controll15 = tk.IntVar()
wrong151 = tk.Radiobutton(self, text="Neural Networks work bad with small amount of data", \
variable= controll15,value=1)
wrong152 = tk.Radiobutton(self, text="Concept of neural network exists since the middle of the mid-twentieth",\
variable= controll15,value=0)
right15 = tk.Radiobutton(self, text="There is no learning rate parameter in training neural networks", \
variable= controll15,value=5)
wrong151.place(x=0, y=60)
wrong152.place(x=0, y=80)
right15.place(x=0, y=100)
def scorer(event):
if int(controll15.get()) > 2:
global score
score += 1
button = tk.Button(self, text="Result",command = lambda: controller.show_frame("Results") )
button.bind("<Button-1>", scorer)
button.pack(side="right")
#END THEME 1
This is the page for showing the actual result (score value). Problem is, while answering all questions correctly, it will show the score initial value (0). On the other hand, the scorecalc function assigned to "print score" button shows the right score... Seems like it can't show from first the actual value, but we have to click on a button to do so...
#RESULT PAGE
class Results(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Your Score:", font=controller.title_font)
label.pack(side="top", fill="x")
button = tk.Button(self, text="return to Menu",
command=lambda: controller.show_frame("StartPage"))
button.pack(side= "bottom")
global score
label = tk.Label(self, text= "%s / 5" %(score), font=controller.title_font)
label.pack()
def scorecalc():
label = tk.Label(self, text="Your Score:", font=controller.title_font)
label.pack(side="top", fill="x")
label = tk.Label(self, text= "%s / 5" %(score), font=controller.title_font)
label.pack()
scorep= tk.Button(self, text ="print score", command=scorecalc)
scorep.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
There are some major issues with your code. Using global variables while using classes is counter productive I think.
One of the major reason why your code does not work is due to the fact you are using variables where class attributes should be used. If you use a variable in a class then after __init__ you will not be able to interact with that variable. be it a widget or a save value like a number or string.
We can fix this by adding the self. prefix to anything that is going to be interacted with from inside the class or from outside the class object.
Also your code does not actually show that you have a global variable called score so I added one to the global namespace for testing.
with that in mind you were using the variable name label for multiple labels. any time you are assigning a variable name they need to be unique.
I have combined the 3 sections of your code to provide a working example that will update the score. This example is not perfect but it is the minimum that is needed to be changed to get the results you are looking for.
Let me know if you have any question:
import tkinter as tk
from tkinter import font as tkfont
score = 1
class theme1Q5(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="5.Question", font=controller.title_font)
label.pack(side="top", fill="x")
Question15 = tk.Label(self, text="Which sentence is not true?")
Question15.place(x=0, y = 30)
self.controll15 = tk.IntVar()
wrong151 = tk.Radiobutton(self, text="Neural Networks work bad with small amount of data",
variable= self.controll15,value=1)
wrong152 = tk.Radiobutton(self, text="Concept of neural network exists since the middle of the mid-twentieth",
variable= self.controll15,value=0)
right15 = tk.Radiobutton(self, text="There is no learning rate parameter in training neural networks",
variable= self.controll15,value=5)
wrong151.place(x=0, y=60)
wrong152.place(x=0, y=80)
right15.place(x=0, y=100)
button = tk.Button(self, text="Result",command = lambda: controller.show_frame("Results"))
button.bind("<Button-1>", self.scorer)
button.pack(side="right")
def scorer(self, event = None):
if int(self.controll15.get()) > 2:
global score
score += 1
self.controller.frames["Results"].update_label()
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
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 (theme1Q5, Results):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("theme1Q5")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
#RESULT PAGE
class Results(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Your Score:", font=controller.title_font)
label.pack(side="top", fill="x")
button = tk.Button(self, text="return to Menu",
command=lambda: controller.show_frame("theme1Q5"))
button.pack(side= "bottom")
global score
self.label2 = tk.Label(self, text= "%s / 5" %(score), font=self.controller.title_font)
self.label2.pack()
def update_label(self):
global score
self.label2.config(text= "%s / 5" %(score))
print(score)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Related
The issue I am having is specifically with the Label widget. In the linked code, the tests for Text widgets and Button widgets both grab the inherited value and display it correctly.
You can find the Label widget in question in class PageTwo
The variable I am trying to inherit and display within the Label is the "num" variable set in the first class.
The goal is to take that variable, set the value in another class, and then display the newly set value later in a Label widget.
I have tried to set the Label to display the variable directly, as a str value, within an f-string, as well as setting a local variable within PageTwo to take the value of TestClass.num
Example of the code in question is:
import tkinter as tk
class TestClass(tk.Tk):
num = None
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Game")
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 (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self,
text="Make a selection",
wraplength=450, justify='center')
label.pack(padx=10, pady=10)
TestClass.num = tk.StringVar()
tk.Radiobutton(self, text="1", variable=TestClass.num, value="1", ).pack()
tk.Radiobutton(self, text="2", variable=TestClass.num, value="2", ).pack()
tk.Radiobutton(self, text="3", variable=TestClass.num, value="3", ).pack()
view_selection = tk.Button(self, text="test selection", command=lambda: print(TestClass.num.get()))
view_selection.pack()
next_page = tk.Button(self, text="Next Page",
command=lambda: controller.show_frame(PageTwo))
next_page.pack(pady=10, padx=10)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label = tk.Label(self, text=TestClass.num.get()
label = tk.Label(self, text=f"The number should show up here -> {TestClass.num.get()} <- ")
label.pack()
text1 = tk.Text(self)
text1.pack()
see_num = tk.Button(self, text="View Number",
command=lambda: text1.insert('1.0', TestClass.num.get()))
see_num.pack(pady=10, padx=10)
app = TestClass()
app.mainloop()
I have come across such uses of controller for a while now but never really got to know where the idea arose from. Anyway over here I see the problem might actually be in the program flow(when you instantiate with F(container, self) you are executing the __init__ of that class, hence the values are already being set.
When you select each item in the radio button, you want the value of the label to appropriately edit itself. So for that I think static variables are more appropriate(to access the widgets inside another class) and you can use command to fire a callback.
Also you need to fix the tristate issue of your Radiobutton, by giving different initial value to the StringVar to not be equal to the tristatevalue of Radiobutton or giving different tristatevalue to each radiobutton or to use ttk.Radiobutton that does not use this tristatevalue.
So the changes to be made for PageTwo are to create some static variables:
class PageTwo(tk.Frame):
label = ''
text = ''
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
PageTwo.text = "The number should show up here -> {} <- " # {} so we can `format` it to be whatever text we want, later
PageTwo.label = tk.Label(self, text=self.text.format(''))
PageTwo.label.pack()
...
...
And in PageOne, you need to set a command for Radiobutton that will be called each time an option is changed.
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
...
TestClass.num = tk.StringVar(value=' ')
command = lambda *args: PageTwo.label.config(text=PageTwo.text.format(TestClass.num.get()))
tk.Radiobutton(self, text="1", variable=TestClass.num, value="1",command=command).pack()
tk.Radiobutton(self, text="2", variable=TestClass.num, value="2",command=command).pack()
tk.Radiobutton(self, text="3", variable=TestClass.num, value="3",command=command).pack()
...
...
Another method I think possible is to create a function to create widgets, and load that up later when the page is supposed to be showed.
I have this code here and I want to pass values from one class (StartPage), to another (PageOne). I made a method in my controller "get_page" that let me access to page data among classes. So, I have an entry in StartPage and i want to pass its value to PageOne. So, the code runs, but in PageOne there is a print for debug. As soon as i start the program it automatically run all the code, almost like if PageOne is called even if I don't press the button. And the value I want to pass to the second page never gets passed. Can anyone help me out here please?
Thanks in advance!
import tkinter as tk # python 3
from tkinter import font as tkfont
from typing_extensions import IntVar # python 3
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, PageOne):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
def get_page(self, classname):
'''Returns an instance of a 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
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Start Page: insert value", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
self.some_input = tk.StringVar()
self.some_entry = tk.Entry(self, width=8)
self.some_entry.pack()
self.some_input = self.some_entry.get()
button1 = tk.Button(self, text='Next Page', command=lambda: controller.show_frame("PageOne"))
button1.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
start_page = self.controller.get_page('StartPage')
value = start_page.some_entry.get()
print ('The value stored in StartPage entry = %s' % start_page.some_input)
label = tk.Label(self, text="This is page 1, the value stored is" + str(value), font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
You need to find a way to notify PageOne to update the label whenever it is shown by show_frame(), one of the way is via virtual event using event_generate() function:
class SampleApp(tk.Tk):
...
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
# notify frame that it is raised via virtual event
frame.event_generate("<<Raised>>")
...
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
# save a reference of 'StartPage'
self.start_page = self.controller.get_page('StartPage')
# use instance variable 'self.label' instead of local variable 'label'
self.label = tk.Label(self, font=controller.title_font)
self.label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
# bind the virtual event
self.bind("<<Raised>>", self.on_raised)
def on_raised(self, event):
self.label.config(text=f"This is page 1, the value stored is '{self.start_page.some_entry.get()}'")
Apologies if the title is a bit broad.
I am creating a Tkinter app with multiple pages and I'm using this piece of code in order to do so.
Each page is a frame and frames are raised by calling the 'show_frame' function. I have no problem with switching between pages using buttons, however I want to run a certain function and change pages if a condition is met.
Below is an example:
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
def doSomething():
...
if x == y:
"RAISE PAGE ONE"
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
As you can see, the doSomething function is outside of any class. How would I go about raising PageOne from this function.
The easiest answer would be to make doSomething() a method of SampleApp. You would then have access to the method show_frame. However, your question seems to imply this isn't an option.
Failing this, I would advise passing app to the function, and then calling app.show_frame("PageName").
If you don't want to pass a pointer to app as an argument, then you could pass doSomething the function app.show_frame as foo, and then call foo("PageName") when you want the page to be shown.
E.g.
def doSomething(foo):
'''some code'''
foo("page name")
doSomething(app.show_frame)
How do I change the geometry of the window and label when I have multiple frames?
Without frames, my code would be:
nGui = Tk()
nGui.geometry("500x500")
But I'm unsure of what 'nGui' is in below code (my whole code as requested). Therefore when this is run it comes up as a very small window. I think it might be 'tk.Tk' but when i tried to edit it, it just made a new window.
class DietBuddy(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, PageOne, Diet_Finder):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="HazaTea Productions", font=TITLE_FONT)
label.place(relx=.5, rely=.5, anchor="center")
time.sleep(2)
button = tk.Button(self, text="Continue",
command=lambda: controller.show_frame("PageOne"))
button.place(relx=.5, rely=.6, anchor="center")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Find Diet",
command=lambda: controller.show_frame("Diet_Finder"))
button.pack()
class Diet_Finder(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Diet Finder", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Find my Diet!",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = DietBuddy()
app.mainloop()
Thank you in advance - if this is in the wrong place, please have mercy and tell me I'm new to this site.
DietBuddy class subclassed Tk. So call geometry method against the DietBuddy instance:
if __name__ == "__main__":
app = DietBuddy()
app.geometry('500x500') # <---
app.mainloop()
Hi i got some code from an answer on Switch between two frames in tkinter which im trying to modify so a button in the StartPage class can call a function called msg in PageOne class.
But im getting this error:
AttributeError: 'Frame' object has no attribute 'msg'
Here is the code so far i marked out the modifications i made to the code.
import tkinter as tk # python3
#import Tkinter as tk # python
TITLE_FONT = ("Helvetica", 18, "bold")
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.parent = parent #<-- my mod
label = tk.Label(self, text="This is the start page", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
self.button3 = tk.Button(text='Calling msg in another class', command=self.parent.msg)#<-- my mod
button1.pack()
button2.pack()
button3.pack()#<-- my mod
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.parent = parent #<-- my mod
label = tk.Label(self, text="This is page 1", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
def msg(self): #<-- my mod
print("IT WORKS!!")
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Could anyone help me out?
Since you're instantiating all your classes in a loop, the easiest way to add references between them is probably to do it after that loop. Remove those references from inside the class, as they won't be valid until after instantiation. Note how button3 is no longer created or packed in StartPage, but rather in SampleApp.
for F in (StartPage, PageOne, PageTwo):
...
self.frames['StartPage'].pageone = self.frames['PageOne']
self.frames['StartPage'].button3 = tk.Button(
text='Calling msg in another class',
command=self.frames['StartPage'].pageone.msg) #<-- my mod
self.frames['StartPage'].button3.pack() #<-- my mod
Try this:
#code to get a page and use it inside any page
#1. create a variable name ex my_pageTwo
#2. show and get frame(page)
#3. now you can use a function from page
my_pageTwo = self.show_frame(PageTwo)
#
my_pageTwo = self.get_page(PageTwo)
#4. example
my_pageTwo.myfunction() #without self
#another example from my tkinter app:
#this function is inside main page:
def open_page8_and_ch_list(self):
if Pages.EEG_raw != '':
page_8 = self.show_frame(PageEight)
page_8 = self.get_page(PageEight)
self.show_frame(PageEight)
page_8.list_initial_ch_names()
else:
self.show_frame(PageEight)
message1_pg8(self)
def message1_pg8(self):
lines = ['Hey! Open a file to edit.']
tkinter.messagebox.showinfo('Myapp', "\n".join(lines))
# On the other hand "open_page8_and_ch_list
#" goes to container1 to open something in page8:
c1_button7 = tk.Button(container1,
text='Edit inicial EEG',
command=lambda: open_page8_and_ch_list(self))
c1_button7.grid(row=0, column=7))
I got stuck with this also, but after some tweaking and grasping the whole width of the code:
self.controller.frames['YourFrameName'].method()
You see everything has been instantiated and stored in a dictionary in the sampleapp class. And every other frame will have reference to the base 'sampleapp' class. So its as simple as referencing the base app and calling the frame that has the method that we want.