0

I've been following Sentdex's playlist "GUI's with Tkinter (Intermediate)" and I can't figure out how to give information to a page. This is what I have so far

class Project(tk.Tk):
  def init(self, *args, **kwargs):
      tk.Tk.init(self, *args, *kwargs)
      tk.Tk.wm_title(self, "Project")
      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 (HomePage,PageOne, PageTwo):
          frame = F(container, self)
          self.frames[F] = frame
          frame.grid(row=0, column=0, sticky="nsew")
      self.show_frame(HomePage)
  def show_frame(self, cont):
      frame = self.frames[cont]
      frame.tkraise()

class PageTwo:
  def __init__(self,parent,controller,name):
      tk.Frame.__init__(self,parent)
      self.name=name
      label = tk.Label(self, text=self.name, font=LARGE_FONT)
      label.pack(pady=10, padx=10)
      button = ttk.Button(self, text="Back to Team Page", command=lambda: controller.show_frame(HomePage))
      button.pack()

The PageTwo class has needs to get name on it, but I keep getting a KeyError

frame = self.frames[cont]                                                                   
KeyError: <__main__.Page2 object .!frame.!page2>

What can I do to fix this ?

1 Answers1

0

The code you are copying wasn't designed to pass different information to each page when it is created. That code was designed to require that the pages all take exactly the same arguments when constructing the page.

That being said, it's trivial to change how the pages are constructed.

Start by removing this code:

self.frames = {}
for F in (HomePage,PageOne, PageTwo):
    frame = F(container, self)
    self.frames[F] = frame
    frame.grid(row=0, column=0, sticky="nsew")

Then, add this code in its place:

self.frames = {
    HomePage: HomePage(container, self),
    PageOne:  PageOne(container, self),
    PageTwo:  PageTwo(container, self, name="the name"),
}
self.frames[HomePage].grid(row=0, column=0, sticky="nsew")
self.frames[PageOne].grid(row=0, column=0, sticky="nsew")
self.frames[PageTwo].grid(row=0, column=0, sticky="nsew")

The code in that tutorial was copied from an answer right here on stackoverflow. He did a poor job explaining how the code works, and it has generated many questions that wind up back here on StackOverflow. The original code was definitely not designed to be used by someone starting out with tkinter.

To see the a modified version of the original code and links to other questions about that code, see this answer: https://stackoverflow.com/a/7557028/7432

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • This makes a lot more sense as to why I got the error, but I am trying to make it so that the name variable can be changed whenever I use it. So for the name given for one page would be different than another. Ex: One page has it's name="Tom" and displays Tom on the page, another one has name="Matt" and will display Matt on the page – user15827223 May 04 '21 at 01:42
  • @user15827223: that’s not what you asked in the question. – Bryan Oakley May 04 '21 at 03:06
  • So, @user15827223 Incase thats what you want I would suggest looking also into the tkinter.ttk.notebook widget its a widget with different tabs which can have different names and widgets inside them. Though if you want them in separate windows then it may not work. – typedecker May 04 '21 at 08:23
  • @user15827223: _"One page has it's name="Tom" and displays Tom on the page, another one has name="Matt" and will display Matt on the page "_ - this answer lets you do that. You can pass "Matt" to `HomePage` and "Tom" to `PageOne`. There's nothing to prevent you from doing that. – Bryan Oakley May 04 '21 at 21:06