I've used Tkinter-Designer
to convert a Figma
frame into a python code, I then added that code to the StartPage
class, and used the code mentioned here to switch between the frames.
For some reason, I can't get button_5
to work. When I click button_5
I expect it to switch to PageOne
, but nothing happens. I'm not good with OOP, can you tell me what I'm doing wrong here?
Here is the full code:
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
from pathlib import Path
OUTPUT_PATH = Path(__file__).parent
ASSETS_PATH = OUTPUT_PATH / Path(r"Z:\python\projects\v\code\gui\tmp\TkinterDesigner\build\assets\frame0")
def relative_to_assets(path: str) -> Path:
return ASSETS_PATH / Path(path)
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
canvas = tk.Canvas(
bg="#FFFFFF",
height=724,
width=1056,
bd=0,
highlightthickness=0,
relief="ridge"
)
canvas.place(x=0, y=0)
canvas.create_rectangle(
56.0,
68.0,
954.0,
673.0,
fill="#F2F2F2",
outline="")
canvas.create_rectangle(
56.0,
68.0,
285.0,
673.0,
fill="#D4D3D3",
outline="")
self.button_image_1 = tk.PhotoImage(
file=relative_to_assets("button_1.png"))
button_1 = tk.Button(
image=self.button_image_1,
borderwidth=0,
highlightthickness=0,
command=lambda: print("button_1 clicked"),
relief="flat"
)
button_1.place(
x=56.0,
y=348.0,
width=229.0,
height=37.0
)
self.button_image_2 = tk.PhotoImage(
file=relative_to_assets("button_2.png"))
button_2 = tk.Button(
image=self.button_image_2,
borderwidth=0,
highlightthickness=0,
command=lambda: print("button_2 clicked"),
relief="flat"
)
button_2.place(
x=56.0,
y=312.0,
width=229.0,
height=37.0
)
self.button_image_3 = tk.PhotoImage(
file=relative_to_assets("button_3.png"))
button_3 = tk.Button(
image=self.button_image_3,
borderwidth=0,
highlightthickness=0,
command=lambda: print("button_3 clicked"),
relief="flat"
)
button_3.place(
x=56.0,
y=274.0,
width=229.0,
height=36.0
)
self.button_image_4 = tk.PhotoImage(
file=relative_to_assets("button_4.png"))
button_4 = tk.Button(
image=self.button_image_4,
borderwidth=0,
highlightthickness=0,
command=lambda: print("button_4 clicked"),
relief="flat"
)
button_4.place(
x=56.0,
y=239.0,
width=229.0,
height=36.0
)
self.button_image_5 = tk.PhotoImage(
file=relative_to_assets("button_5.png"))
button_5 = tk.Button(
image=self.button_image_5,
borderwidth=0,
highlightthickness=0,
command=lambda: controller.show_frame("PageOne"),
relief="flat"
)
button_5.place(
x=56.0,
y=201.0,
width=229.0,
height=37.0
)
self.image_image_1 = tk.PhotoImage(
file=relative_to_assets("image_1.png"))
image_1 = canvas.create_image(
617.0,
300.0,
image=self.image_image_1
)
canvas.create_text(
706.0,
574.0,
anchor="nw",
text=" -Jim Rohn",
fill="#000000",
font=("RobotoMono Regular", 14 * -1)
)
canvas.create_text(
433.0,
500.0,
anchor="nw",
text="“Reading is essential for those who seek to rise above the ordinary.” ",
fill="#000000",
font=("RobotoMono Regular", 14 * -1)
)
canvas.create_text(
84.0,
100.0,
anchor="nw",
text="Hello ZZZ!",
fill="#000000",
font=("RobotoMono Bold", 18 * -1)
)
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()
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=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.geometry("1056x724")
app.configure(bg="#FFFFFF")
app.mainloop()
CodePudding user response:
You did not specify the parent when creating those widgets inside StartPage
, so they will be children of the root window. The canvas is large enough to cover those pages so you cannot see them.
Specify the parent (self
) when creating those widgets:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
...
canvas = tk.Canvas(
self, # specify parent
bg="#FFFFFF",
...
)
...
button_1 = tk.Button(
self,
image=...
...
)
...
button_2 = tk.Button(
self,
image=...
...
)
...
button_3 = tk.Button(
self,
image=...
...
)
...
button_4 = tk.Button(
self,
image=...
...
)
...
button_5 = tk.Button(
self,
image=...
...
)
...