This is a minimal example I made to show the problem, and it is extracted from a large project so please forgive the naming. So basically I have an GUI that looks like this:
the connect button and BE\RP... buttons belongs to a frame (control_container), which is like a navigator or tab selector that should always show up, and the info button belongs to another frame (container), which, when you click on BE\RP... buttons, should change to those corresponding frame class, and it does. what confused me is that when clicking the connect button, it should call function connect and do a print. However, it doesn't work: when you click on it, simply nothing happened. But I do know that the program recognize the connect function since it would complain if you delete the function. For contrast, if you click on info on StartPage, it works just fine and print. This is really strange to me.
import tkinter as tk
from tkinter import ttk
from tkinter import *
class emcAutoApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.control_container = tk.Frame(self)
self.control_container.pack(side="top", fill="both", expand = True)
container = tk.Frame(self, width=768, height=576, bg="")
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, BE, RP, PreScan, RSE):
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 get_page(self, page_class):
return self.frames[page_class]
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.frame_controller = controller
#control frame starts here
control_frame = ttk.Frame(self.frame_controller.control_container)
control_frame.pack(side='top')
chamber_frame = Frame(control_frame,
borderwidth=5,
relief=RIDGE,
width=200
)
chamber_frame.pack(side=TOP, expand=YES, fill=X)
chamber_frame_1 = Frame(chamber_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
chamber_frame_1.pack(side=LEFT, expand=YES, fill=X)
chamber_frame_2 = Frame(chamber_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
chamber_frame_2.pack(side=LEFT, expand=YES, fill=X)
connect_button = ttk.Button(chamber_frame_2, text="connect", command=lambda: self.connect)
connect_button.pack()
tab_frame = Frame(control_frame,
borderwidth=5,
relief=RIDGE,
width=500
)
tab_frame.pack(side=TOP, expand=YES, fill=X)
tab_frame_1 = Frame(tab_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
tab_frame_1.pack(side=LEFT, expand=YES, fill=X)
tab_frame_2 = Frame(tab_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
tab_frame_2.pack(side=LEFT, expand=YES, fill=X)
tab_frame_3 = Frame(tab_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
tab_frame_3.pack(side=LEFT, expand=YES, fill=X)
tab_frame_4 = Frame(tab_frame,
borderwidth=1,
relief=RIDGE,
width=100
)
tab_frame_4.pack(side=LEFT, expand=YES, fill=X)
BE_button = ttk.Button(tab_frame_1, text="BE",
command=lambda: self.frame_controller.show_frame(BE))
BE_button.pack()
RP_button = ttk.Button(tab_frame_2, text="RP",
command=lambda: self.frame_controller.show_frame(RP))
RP_button.pack()
PreScan_button = ttk.Button(tab_frame_3, text="PreScan",
command=lambda: self.frame_controller.show_frame(PreScan))
PreScan_button.pack()
RSE_button = ttk.Button(tab_frame_4, text="RSE",
command=lambda: self.frame_controller.show_frame(RSE))
RSE_button.pack()
infobutton = ttk.Button(self, text = "info", command = self.info)
infobutton.pack()
def info(self):
print("info")
def connect(self):
print("connected")
class BE(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.frame_controller = controller
class RP(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.frame_controller = controller
class PreScan(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.frame_controller = controller
class RSE(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.frame_controller = controller
if __name__ == "__main__":
#=== GUI ===#
LARGE_FONT = ("Verdana", 12)
NORM_FRONT = ("Verdana", 10)
app = emcAutoApp()
app.mainloop()