-1

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()
acw1668
  • 40,144
  • 5
  • 22
  • 34
ZZZ
  • 161
  • 1
  • 8
  • You forget to specify the parent of the widgets inside `StartPage`, so they are created as children of root window. – acw1668 Jan 10 '23 at 09:14
  • @acw1668 can you elaborate more please – ZZZ Jan 10 '23 at 11:27
  • Please read [ask] and [mre]. This looks like way too much code to explain the problem. For example, is it necessary to create the *other* buttons in the UI, in order to cause the problem where this button doesn't work? How about the other pages, besides the one that has the button and the target for switching - are they actually necessary? How about the styling on the buttons, the canvas images and text etc. - are they relevant to the problem? If not, exclude them from the example. – Karl Knechtel Jan 10 '23 at 11:52

1 Answers1

0

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=...
            ...
        )
        ...
acw1668
  • 40,144
  • 5
  • 22
  • 34