-2

I have a project I am working on and it requires me to update a frame with new page information depending on what button is clicked.

I have 2 frames in the main page. One frame holds the buttons and the other frame is to be updated on button click. However when I click on a button it seams to remove both buttons and set up the new page on the first frame.

I don't see how this is possible as I have check each frame and they should be separate.

When I run the test1.py page I get this window as expected:

enter image description here

However this is what I get when I press one of the buttons:

enter image description here

I should expect to see the 2 buttons still there and the label now to the right of the buttons. I really cant see how this could be happening.

Here are my example pages.

test1.py contains:

import tkinter as tk
import test2
import test3

class TestApp(tk.Frame):

    def __init__(self, master, *args, **kwargs):
        tk.Frame.__init__(self, master, *args, **kwargs)
        self.button_frame = tk.Frame(self)
        self.button_frame.grid(row=0, column=0)
        self.working_frame = tk.Frame(self)
        self.working_frame.grid(row=0, column=1)

        tk.Button(self.button_frame, text="Test 2", command=lambda: self.update_main_frame("test2")).grid(row=0, column=0)
        tk.Button(self.button_frame, text="Test 3", command=lambda: self.update_main_frame("test3")).grid(row=1, column=0)


    def update_main_frame(self, window_name):
        if window_name == "test2":
            self.reset_working_frame()
            x = test2.TestFrame2(self.working_frame)
            x.grid(row=0, column=0, sticky="nsew")
        if window_name == "test3":
            self.reset_working_frame()
            x = test3.TestFrame3(self.working_frame)
            x.grid(row=0, column=0, sticky="nsew")

    def reset_working_frame(self):
        self.working_frame.destroy()
        self.working_frame = tk.Frame(self)
        self.working_frame.grid(row=0, column=1)



if __name__ == "__main__":
    root = tk.Tk()
    TestApp(root).grid(row=0, column=0, sticky="nsew")
    tk.mainloop()

test2.py contains:

import tkinter as tk

class TestFrame2(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self)
        self.parent = parent
        self.internal_frame = tk.Frame(self)
        self.internal_frame.grid(row=0, column=0, sticky="nsew")

        tk.Label(text="some small label").grid(row=0, column=0)

test3.py contains:

import tkinter as tk  

class TestFrame3(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self)
        self.parent = parent
        self.internal_frame = tk.Frame(self)
        self.internal_frame.grid(row=0, column=0, sticky="nsew")

        tk.Label(text="some larger label!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!").grid(row=0, column=0)
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • If would help if you combined all of this code into a single file. – Bryan Oakley Apr 16 '18 at 21:56
  • 1
    At least part of the problem is that you aren't passing `parent` to `Frame.__init__` in `TestFrame2` and `TestFrame3` so those widgets are getting added to the root window. – Bryan Oakley Apr 16 '18 at 22:00
  • @BryanOakley Thanks. It is something I should have seen on my own. Now to work it into my program tomorrow when I get back to my desk. I didn't combine the example into one file because I considered the problem could be related to how I am importing or because my pages are all different files. So I figured writing my example would be best to follow the same logic. – Mike - SMT Apr 16 '18 at 22:32
  • I am not sure what the downvote is for. I provided a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). Would be nice to know the reason for downvote so I can improve my questions in the future. – Mike - SMT Apr 17 '18 at 13:25
  • If I were to guess about the downvote, I would say it's because your question doesn't show any signs of you attempting to solve the problem yourself before asking the question. A good question includes a description of things you've tried to solve the problem, the results of debugging, etc. – Bryan Oakley Apr 17 '18 at 13:52
  • @BryanOakley Hum. well I worked on the problem for hours and tried many different things. But I guess its fine. It ended up being a silly mistake that I should have noticed anyway. – Mike - SMT Apr 17 '18 at 13:53
  • We can't know what you've tried unless you tell us. – Bryan Oakley Apr 17 '18 at 13:55
  • @BryanOakley yes I understand. That is why I said its is fine. It would be difficult to add all I had tried into my question and at this point it would not matter knowing the answer has already been provided. – Mike - SMT Apr 17 '18 at 13:59

1 Answers1

2

You didn't give a parent frame to the TestFrame or the Label, so both default to root. Try this:

class TestFrame2(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent) # add parent Frame
        self.parent = parent
        self.internal_frame = tk.Frame(self)
        self.internal_frame.grid(row=0, column=0, sticky="nsew")

        lbl = tk.Label(self.internal_frame, text="some small label") # add parent Frame
        lbl.grid(row=0, column=0)

Also, putting the initialization and layout on the same line leads to bugs. Use 2 lines.

Novel
  • 13,406
  • 2
  • 25
  • 41
  • Thanks for the info. Such a simple mistake. I could not even see it and I know better. Been staring at this program for 2 long. Over 1000 lines of code and such a simple mistake took 4 hours to figure out lol. – Mike - SMT Apr 16 '18 at 22:31
  • @Mike-SMT BTW, tkinter automatically assigns the instance variable `self.master`, so you don't need the `self.parent = parent` line. – Novel Apr 16 '18 at 22:49